生成器
协程的核心就是上下文切换,在Python中最简单的实现是用生成器
生成器有个方法 send()
可以从调用者向生成器函数发送数据,这样就可以在生成器中 yield future
表示要等待 future 的结果,然后把上下文切换到调用者,等 future 结果准备好后调用者再 send(future.result())
给生成器发送结果,并把上下文切换到生成器函数
def generator_function():
# 正常情况应用loop.create_future()
result = yield asyncio.Future()
print('future结果:', result)
return 2
def main():
generator = generator_function()
try:
future = generator.send(None)
# 假设某个回调调用了future.set_result
future.set_result(1)
future = generator.send(future.result())
except StopIteration as e:
print('generator_function结果:', e.value)
输出:
future结果: 1
generator_function结果: 2
但是在生成器函数中调用子生成器会很麻烦:
def generator_function2():
# 正常情况应用loop.create_future()
result = yield asyncio.Future()
print('future结果:', result)
return 2
def generator_function():
generator2 = generator_function2()
try:
future = generator2.send(None)
result = yield future
future = generator2.send(result)
except StopIteration as e:
print('generator_function2结果:', e.value)
return 3
def main():
generator = generator_function()
try:
future = generator.send(None)
# 假设某个回调调用了future.set_result
future.set_result(1)
future = generator.send(future.result())
except StopIteration as e:
print('generator_function结果:', e.value)
输出:
future结果: 1
generator_function2结果: 2
generator_function结果: 3
于是有了 yield from
的语法糖,可以把流程控制交给子生成器,即子生成器 yield
直接切换上下文到调用者,调用者 send()
直接给子生成器发送数据。这样上面的例子可以写成: