def gen():
for i in range(10):
x = yield i
print(x)
用这个举例说明:
从程序执行流程来看,赋值操作的 = 语句都是从右边开始执行的
明确这一点,就很好理解了.
来看 x = yield i 这个表达式
如果这个表达式只是x = i,
相信每个人都能理解是把i的值赋值给了x(虽然python是引用,不过不碍事)
而现在等号右边是一个yield i,所以先要执行yield i,然后才是赋值
yield把i值返回到了调用者那里
这个表达式的下一步操作:赋值
却因为等号右边的yield被暂停了
换句话说x = yield i才执行了一半
当调用者通过send(var)回到生成器函数时
是回到之前那个赋值表达式被暂停的那里
所以接下来执行x = yield i的另一半,那就是这个赋值操作啦
这个值正是调用者通过send(var)发送进生成器的值
然后被打印,然后循环下一次执行,然后又来到yield i,然后又暂停,重复以上描述
send(var)之前必须启动这个生成器,为什么呢?
因为最开始,gen()函数运行到yield i时,是从gen()把i的值抛回给调用者
所以最开始send进去一个具体值,是几个意思?顺序不对啊!!
现在人家并不是回到gen()生成器,而是第一次运行gen()函数时人家要从gen()那里出来啊
send(var)是发生在回到gen()时的操作,而不是从gen()出来时的操作,这是需要明确差别的一点
从方便理解的角度上来说
启动生成器最好还是使用next(),虽然send(None)也可以
因为启动的时候总是从生成器回到调用者的过程