当前位置: 首页 > 编程笔记 >

浅谈Python生成器generator之next和send的运行流程(详解)

田佐
2023-03-14
本文向大家介绍浅谈Python生成器generator之next和send的运行流程(详解),包括了浅谈Python生成器generator之next和send的运行流程(详解)的使用技巧和注意事项,需要的朋友参考一下

对于普通的生成器,第一个next调用,相当于启动生成器,会从生成器函数的第一行代码开始执行,直到第一次执行完yield语句(第4行)后,跳出生成器函数。

然后第二个next调用,进入生成器函数后,从yield语句的下一句语句(第5行)开始执行,然后重新运行到yield语句,执行后,跳出生成器函数,后面再次调用next,依次类推。

下面是一个列子:

 def consumer():
   r = 'here'
   for i in xrange(3):
     yield r
     r = '200 OK'+ str(i)

 c = consumer()
 n1 = c.next()
 n2 = c.next()
 n3 = c.next()

了解了next()如何让包含yield的函数执行后,我们再来看另外一个非常重要的函数send(msg)。其实next()和send()在一定意义上作用是相似的,区别是send()可以传递yield表达式的值进去,而next()不能传递特定的值,只能传递None进去。因此,我们可以看做c.next() 和 c.send(None) 作用是一样的。

需要提醒的是,第一次调用时,请使用next()语句或是send(None),不能使用send发送一个非None的值,否则会出错的,因为没有Python yield语句来接收这个值。

下面来着重说明下send执行的顺序。当第一次send(None)(对应11行)时,启动生成器,从生成器函数的第一行代码开始执行,直到第一次执行完yield(对应第4行)后,跳出生成器函数。这个过程中,n1一直没有定义

下面运行到send(1)时,进入生成器函数,注意这里与调用next的不同。这里是从第4行开始执行,把1赋值给n1,但是并不执行yield部分。下面继续从yield的下一语句继续执行,然后重新运行到yield语句,执行后,跳出生成器函数。

即send和next相比,只是开始多了一次赋值的动作,其他运行流程是相同的。

 def consumer():
   r = 'here'
   while True:
     n1 = yield r
     if not n1:
       return
     print('[CONSUMER] Consuming %s...' % n1)
     r = '200 OK'+str(n1)

 def produce(c):
   aa = c.send(None)
   n = 0
   while n < 5:
     n = n + 1
     print('[PRODUCER] Producing %s...' % n)
     r1 = c.send(n)
     print('[PRODUCER] Consumer return: %s' % r1)
   c.close()

 c = consumer()
 produce(c)

 运行结果:

[PRODUCER] Producing 1...
[CONSUMER] Consuming 1...
[PRODUCER] Consumer return: 200 OK1
[PRODUCER] Producing 2...
[CONSUMER] Consuming 2...
[PRODUCER] Consumer return: 200 OK2
[PRODUCER] Producing 3...
[CONSUMER] Consuming 3...
[PRODUCER] Consumer return: 200 OK3
[PRODUCER] Producing 4...
[CONSUMER] Consuming 4...
[PRODUCER] Consumer return: 200 OK4
[PRODUCER] Producing 5...
[CONSUMER] Consuming 5...
[PRODUCER] Consumer return: 200 OK5

以上这篇浅谈Python生成器generator之next和send的运行流程(详解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持小牛知识库。

 类似资料:
  • 本文向大家介绍Python生成器(Generator)详解,包括了Python生成器(Generator)详解的使用技巧和注意事项,需要的朋友参考一下 通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。 所以,如果列表元素可以

  • 本文向大家介绍浅谈Python中列表生成式和生成器的区别,包括了浅谈Python中列表生成式和生成器的区别的使用技巧和注意事项,需要的朋友参考一下 列表生成式语法: 二者的区别很明显: 一个直接返回了表达式的结果列表, 而另一个是一个对象,该对象包含了对表达式结果的计算引用, 通过循环可以直接输出 结果     当表达式的结果数量较少的时候, 使用列表生成式还好, 一旦数量级过大, 那么列表生成式

  • 本文向大家介绍python生成式的send()方法(详解),包括了python生成式的send()方法(详解)的使用技巧和注意事项,需要的朋友参考一下 随便在网上找了找,感觉都是讲半天讲不清楚,这里写一下。  输出: 为什么会这样呢,点进send就能看到一句话 send:Resumes the generator and "sends" a value that becomes the resul

  • 本文向大家介绍老生常谈Python之装饰器、迭代器和生成器,包括了老生常谈Python之装饰器、迭代器和生成器的使用技巧和注意事项,需要的朋友参考一下 在学习python的时候,三大“名器”对没有其他语言编程经验的人来说,应该算是一个小难点,本次博客就博主自己对装饰器、迭代器和生成器理解进行解释。 为什么要使用装饰器 什么是装饰器?“装饰”从字面意思来谁就是对特定的建筑物内按照一定的思路和风格进行

  • 问题内容: 基于生成器的协程具有一种方法,该方法允许调用方和被调用方之间进行双向通信,并从调用方恢复生成的生成协程。这是将生成器变成协程的功能。 尽管新的本机协程为异步I / O提供了出色的支持,但我看不出如何获得与之等效的协程。明确禁止使用in函数,因此本机协程只能使用一条语句返回一次。尽管表达式将新值带入协程中,但这些值来自被调用方,而不是调用方,并且等待的调用从每次开始就进行评估,而不是从中

  • generator 也就是生成器的英文拼写,它的主要作用是生成大批量的数据 方法一 (x for x in ['a', 'v']) 其实也就是把上一章迭代方法中的[]换成了(),那么返回的对象就不同了,前者是生成了一个list后者是生成了一个生成器。 其实跟js中的generator是一样的,打印出来这个生成器的内容只需要使用next()方法就OK了 l = ( x for x in ['1','