现在在学习Python的3.4,遇到了协程的慨念和yield from语法,大为疑惑,所以写了这篇博客,首先会写yield、yield from、coroutine和gevent,最后就是利用asynaio开发的一系列库了。
2015年08月06日23:52:54了,就写这么多吧,以后持续更新。
不知道CSDN的markdown能不能换css样式。。。
yield在Python 2.7的时候就接触过yield关键词:
def foo(m):
n = 0
while n <= m:
yield n
n += 1
如果在终端输入(Python 3.4):
>>>for i in foo(5):
... print(i)
...
0
1
2
3
4
5
之前就知道List和Dict类型的对象可以用for ... in ...的语法,现在用yield关键词后生成的对象也可以这样用了。随便百度一下就知道用yield装饰的对象变为了Generator类型。
next和send伴随着yield一定会有next和send这两个方法。本质上说,这两个方法没有什么区别。
next 返回Generator的下一个值,然后Generator挂起,此时就需要send方法来继续唤醒Generatorsend 如果对于一个Generator对象g,调用g.send(None)(传入None型),那么效果和调用next(g)一样;如果调用g.send(Value)(传入具体的值),就相当于yield返回的值。写敲出下面的代码,命名为test.py:
import itertools
def g():
print(‘--start--‘)
for i in itertools.count():
print(‘--yielding %i--‘ % i)
try:
ans = yield i
except GeneratorExit:
print(‘--closing--‘)
raise
except Exception as e:
print(‘--yield raised %r‘ % e)
else:
print(‘--yield returned %s--‘ % ans)
然后在终端输入:
>>>from test import *
>>>it = g()
>>>next(it)
--start--
--yielding 0--
0
>>>it.send(100)
--yield returned 100--
--yielding 1--
1
>>>it.send(1000)
--yield returned 1000--
--yielding 2--
2
>>>next(it)
--yield returned None--
--yielding 3--
3
来分析一下代码:
next(it)第一次执行该条语句得到it的下一个值0,然后it挂起,等待终端的指令it.send(100),上文已说该方法和next()没什么区别,相当于执行了test.py中的yield i,只不过返回的是传入的参数的值。因为执行了yield i语句,所以继续执行下面的语句print(‘--yield returned %s--‘ % ans)next(it),相当于从上一步的yield i后面开始执行,因为执行yield i的时候,直接退出了g,所以ans并没用被赋值。Any values that the iterator yields are passed directly to the caller.
PEP 0380 – Syntax for Delegating to a Subgenerator
所以只能这样解释了,那为什么用send就可以赋值呢?说明这两个方法还是有些不一样?
未完待续
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/mr_zys/article/details/47325923