python yield 生成器用法

    xiaoxiao2025-07-12  5

    1、yield 和 next(),send()方法

    总结:可以把send()看成是next()的升级版。send()不仅能像next()一样触发生成器的一个迭代,还能传入一个值给 yield语句。 看下面一个列子:

    def func(): y = 1 while True: x = yield y y += 1 print('接收了x = {}'.format(x)) f = func() # f是一个初始化好的生成器 # print('传入send(100):', f.send(100)) # 在生成器刚初始化时,不能用send()传入数据,否则会报错。 可以用send(None)。 print('第一次 next():', next(f)) # 生成器启动(激活生成器),代码停在‘x = yield y’这里, # 传入的值为None, next()相当于send(None),产生第一个yield值1。 print('第二次 next():', next(f)) # next()函数触发生成器,从‘y+=1’开始运行,y变成了2, # 最后再次停在‘x=yield y’处,产生一个yield值2,因为没有接收到send值,所以x=None。 print('传入send(10):', f.send(10)) # 此时收到send(10), yield语句被赋值为10,即‘x=yield y =10’,⇨ ‘x=10’。 # 但不影响yield自身产生的值,会接着运行‘y+=1‘,y变成3, # 所以仍会有一个‘next()’产生一个yield值3,再次停在‘x=yield y’处。 # 此处敲黑板:send()带有next()功能。 print('第三次 next():', next(f)) # next()函数触发生成器,从’y+=1‘开始运行,y变成了4, # 然后再次停在’x=yield y‘,产生一个yield值4,没有接收到send值,所以x=None。 f.close() # close()关闭生成器. #print('第四次 next():', next(f)) # 因为 close()关闭生成器,所以会产生StopIteration错误。

    运行后的结果为:

    第一次 next(): 1 接收了x = None 第二次 next(): 2 接收了x = 10 传入send(10): 3 接收了x = None 第三次 next(): 4

    注:这里有一个 send( ) 知识点需要注意下

    send() 有两个功能: 1、向当前迭代的“位置"发送值。 2、抛出下一个值。 例子如下:

    def fun_yield(): yield 1 a = yield 2 print(a) yield 3 return 4 f = fun_yield() print(next(f)) # 启动生成器,第一次迭代出 1, 代码停在此处。 print(f.send('这是在第二次迭代中传递的值')) # 这时send传进去的值是赋给代码所停的yield位置处,即上面 1 的地方。 # 再实现”next()“功能,迭代出 第二个值 2,然后代码停在 yield 2 的地方 。 print(f.send('这是在第三次迭代中传递的值')) # 因为此时代码停在 yield 2 的地方,所以这时 send()进去的值 赋给了 a,相当于给a重新赋值了。 # 再实现 next() 功能,代码运行到下个 yield 处,所以会 print(a),再迭代出 3。

    得到的结果为:

    1 2 这是在第三次迭代中传递的值 3

    这说明,虽然 a = yield 2 是在第二个迭代中的,但实际上 a 的值是第三次迭代时传进去的。 具体理解,可以看上面代码的注释。

    2 yield + return

    def foo(): # 定义一个返回 0,1,2,3, 4 五个数字的生成器。 n = 0 while True: yield n n = n+1 if n == 5: break return 1111 # 前5次的迭代不都会执行return, # 等foo()中的元素迭代完后,再一次迭代会报错: “StopIteration”,并返回一个 1111 的值。 def func(): a = yield from foo() # 调用 foo()生成器。 print('foo() 最后的返回值 a = {}'.format(a)) # 当foo()生成器的元素全部迭代完后,再次调用 next(),就执行这句代码。 yield 2222 # 调用 next()执行上面这句代码后,马上执行这句代码,yield 出 2222。 f = func() for i in range(6): print(next(f)) # 迭代6次,前面5次从 foo()中取出, # 第6次迭代时,foo()产生一个StopIteration错误,并返回一个值 1111 给func()中的a # 然后 func()自身 yield 出 2222 给第六次的迭代结果。
    最新回复(0)