下面所有的代码只为了说明asyncio.Future , 至于为什么要写这玩意,主要是针对tornado 中的yield .
tornado中现在 tornado.gen.coroutine 中全部使用的asyncio.Future.
算了,我喝醉了,一瓶白酒下肚,在车上瞎写, 下面的东西都在瞎搞.
先通过代码说明生成器的演变, 再说明gen 与 Future对象类似的地方;
如若对生成器->协程->Future , yield from不熟悉,下面的代码很可能有难度,我博客里有很多关于生成器协程的文章.
关于yiled from 的其他文章:
为什么使用 yield from :
//普通函数
def f1():
print("f1")
return 1
//生成器
def f2():
print("f2")
rs = yield f1() //首先调用f1() , 相当于 yield 1
print("end :" , rs)
//开启生成器
for i in f2():
print("in for:" , i)
如果第一个普通函数也变成了生成器怎么办 ?
def f1(): #此生成器将无法被使用
print("f1")
yield 1 #修改这行代码
def f2():
print("f2")
rs = yield f1() #此时将把 f1() 这个生成器产出去
print("end :" , rs)
for i in f2():
print("in for:" , i)
############
输出:
f2
in for: <generator object f1 at 0x06C2CDB0>
end : None
因此 yield from 就此诞生了, 其作用就是等待一个生成器对象执行完,作用与await 一致;
def f1():
print("f1")
yield 1
def f2():
print("f2")
rs = yield from f1() #修改这行代码
print("end :" , rs)
for i in f2():
print("in for:" , i)
#输出:
f2
f1
in for: 1
end : None
yield from 将调用iter() 与 next() [相当于for .. in ..] 后一个生成器对象, 相当于迭代一个可迭代对象一样.
具体关于 yield from 可参考 : yield from实现
生成器与 Future对象类似的地方, 这么说吧. 其实是生成器的send 与 Future.setResult 类似的地方
一个简单的生成器例子:
def f1():
print("f1 start")
rs = yield 1
print("yield recvied:" , rs)
rs = yield 2
print("yield recvied:", rs)
import time
g = f1() #创建生成器对象
try:
r = next(g) #激活到第一个yield 为止
print("执行到第一个yield , result:" , r) #yield 1
time.sleep(1)
print("准备发送 100 到生成器")
r = g.send(100) # 直到 g.send 被调用前, 此生成器是不运行的(暂停)
print("执行到第2个yield , result:", r)
time.sleep(2)
print("准备发送 200 到生成器")
g.send(200) #同样, 直到g.send 调用前, 生成器停止继续运行
except Exception as e:
print("生成器停止")
从上面可知, 直到生成器对象.send (或者可以使用 next(生成器对象) ) 被调用前, 生成器本身是不执行的,
生成器全由客户(我们) 通过next() / send() 来推动进程.
同样的对于asyncio.Future 这个对象是对生成器的一次包装,当使用 await Future() 或 yield from Future() 时,
此协程将等待, 直到Future.setResult() 被调用,才会返回. 与twisted中Deferred对象的callback() 一致;
关于asyncio , 协程都可在我博客中搜索到.
#此文章是我喝醉后写的. 别太在意