Python生成器generator之next和send运行流程

next:

1 def consumer():
2     r = 'here'
3     for i in xrange(3):
4         yield r
5         r = '200 OK'+ str(i)
6
7  c = consumer()
8  n1 = c.next()
9  n2 = c.next()
10 n3 = c.next()

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

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

后面再次调用next,依次类推。

 

 

send:

 

1 def consumer():
2     r = 'here'
3     while True:
4         n1 = yield r
5         if not n1:
6             return
7         print('[CONSUMER] Consuming %s...' % n1)
8         r = '200 OK'+str(n1)
9
10 def produce(c):
11     aa = c.send(None)
12     n = 0
13     while n < 5:
14         n = n + 1
15         print('[PRODUCER] Producing %s...' % n)
16         r1 = c.send(n)
17         print('[PRODUCER] Consumer return: %s' % r1)
18     c.close()
19
20 c = consumer()
21 produce(c)
 
再来看另外一个非常重要的函数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相比,只是开始多了一次赋值的动作,其他运行流程是相同的。
 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
生成器Python中的一个对象,它按照某种规律来生成元素的对象。与列表不同,生成器保存了产生元素的算法,并记录了游标的位置,以便下次继续获取数据而不是从头开始。生成器可以通过调用next()方法来逐个获取值,它不会保存所有的数据,每次调用只返回一个值,既能享受列表的好处,又不会占用过多的内存空间。创建生成器可以将一个列表生成式的方括号\[\]改为圆括号(),例如`(i for i in range(0,5))`就创建了一个生成器。\[1\]\[2\] 在使用生成器时,需要注意一些细节。例如,在使用send()方法之前,需要先通过next()方法生成一次数据,否则会出现TypeError: can't send non-None value to a just-started generator的错误。另外,生成器可以使用yield语句来产生值,并可以通过send()方法向生成器发送数据。下面是一个示例代码: ```python def demo(): for i in range(10): res = yield i print('send传入的数据:', res) g = demo() print('next生成的数据:', next(g)) print('send生成的数据:', g.send(6)) ``` 以上代码中,通过调用next(g)获取生成器的下一个值,然后使用g.send(6)向生成器发送数据。\[3\] #### 引用[.reference_title] - *1* [python之三大法器——生成器](https://blog.csdn.net/qq_29049499/article/details/121330302)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [python——生成器详解(2022年9月5日更新了内容)](https://blog.csdn.net/YZL40514131/article/details/119989244)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值