现在在学习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
就可以赋值呢?说明这两个方法还是有些不一样?
未完待续
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-25 22:02:44