生成器和Future对象类似的地方与yield from

版权声明: https://blog.csdn.net/dashoumeixi/article/details/89289510

下面所有的代码只为了说明asyncio.Future  , 至于为什么要写这玩意,主要是针对tornado 中的yield .

tornado中现在  tornado.gen.coroutine 中全部使用的asyncio.Future.

算了,我喝醉了,一瓶白酒下肚,在车上瞎写, 下面的东西都在瞎搞.

先通过代码说明生成器的演变, 再说明gen 与 Future对象类似的地方;

如若对生成器->协程->Future , yield from不熟悉,下面的代码很可能有难度,我博客里有很多关于生成器协程的文章.

关于yiled from 的其他文章:

 yield from 生成器 协程

 yield 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 , 协程都可在我博客中搜索到.

#此文章是我喝醉后写的. 别太在意

猜你喜欢

转载自blog.csdn.net/dashoumeixi/article/details/89289510