yield

作者: 一把猫粮 | 来源:发表于2018-09-30 16:28 被阅读0次

yield 生成器, 当函数中有yield, 那么这个函数编程生成器, 对其进行函数调用, 不会执行, 会返回一个生成器对象

In [1]: def createNum():
   ...:     print("__start__")
   ...:     a, b = 0, 1
   ...:     for i in range(5):
   ...:         print("__1__")
   ...:         yield b
   ...:         print("__2__")
   ...:         a, b = b, a+b
   ...:         print("__3__")
   ...:     print("__stop__")
   ...:


In [3]: a
Out[3]: <generator object createNum at 0x000001FEF6C8AB48>

In [5]: type(a)
Out[5]: generator

生成器对象使用next()开始执行

In [4]: next(a)
__start__
__1__
Out[4]: 1

可见, 一次next()调用, 程序从上往下执行, 恰好到yield b处停止, 并返回yield后面变量的值1
进行下一次next()调用

In [6]: next(a)
__2__
__3__
__1__
Out[6]: 1

程序从上一次next()执行的位置继续向下执行, 直到下一次遇到yield b

通过for执行, 不会出现StopIteration错误

In [7]: for each in a:
   ...:     print(each)
   ...:
__2__
__3__
__1__
2
__2__
__3__
__1__
3
__2__
__3__
__1__
5
__2__
__3__
__stop__
In [1]: def test():
   ...:     i = 0
   ...:     while i < 5:
   ...:         temp = yield i
   ...:         print(temp)
   ...:         i += 1
   ...:

试想, temp的值是否是yield后面i的值

In [4]: t.__next__()
Out[4]: 0

第一次执行, 到yield停止, 返回i的值

In [5]: t.__next__()
None
Out[5]: 1

第二次执行, 到yield停止, 期间打印None, 最后返回i的值, 可见, 其并未如我们预期所想, yield i整体没有任何值, 那么如何才能实现给temp赋值的效果呢?

In [6]: t.send('send')
send
Out[6]: 2

发现, send()next()都可以让生成器向下执行, 不同的是, send(arg)通过一个参数, 给yield i整体赋值

需要注意的是, 在生成器的第一次使用时, 由于程序并未执行到yield, 所以此时通过send()函数传参调用生成器会报错TypeError: can't send non-None value to a just-started generator, 但是可以传入参数None 来使生成器走到yield


协程简单实现

In [25]: def test1():
    ...:     while True:
    ...:         print('__1__')
    ...:         yield None
    ...:

In [26]: def test2():
    ...:     while True:
    ...:         print('__2__')
    ...:         yield None
    ...:

In [27]: t1 = test1()

In [28]: t2 = test2()

In [29]: import time

In [30]: while True:
    ...:     t1.__next__()
    ...:     t2.__next__()
    ...:     time.sleep(1)
    ...:
__1__
__2__
__1__
__2__
__1__
__2__
__1__
__2__
__1__
__2__
__1__
__2__
__1__
__2__

通过生成器的中断特性以及next()的执行, 实现程序间的跳转, 完成简单协程

相关文章

网友评论

      本文标题:yield

      本文链接:https://www.haomeiwen.com/subject/apbwoftx.html