本文主要向大家介绍了Python语言入门的协程的底层实现,通过具体的代码向大家展示,希望对大家学习Python语言入门有所帮助。
生成器
协程的核心就是上下文切换,在Python中最简单的实现是用生成器
生成器有个方法 send() 可以从调用者向生成器函数发送数据,这样就可以在生成器中 yield future 表示要等待 future 的结果,然后把上下文切换到调用者,等 future 结果准备好后调用者再 send(future.result()) 给生成器发送结果,并把上下文切换到生成器函数
def generator_function():
# 正常情况应用loop.create_future()
result = yield asyncio.Future()
print('future结果:', result) return 2def 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)12345678910111213141516
输出:
future结果: 1generator_function结果: 212
但是在生成器函数中调用子生成器会很麻烦:
def generator_function2():
# 正常情况应用loop.create_future()
result = yield asyncio.Future()
print('future结果:', result) return 2def 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 3def 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)12345678910111213141516171819202122232425262728
输出:
future结果: 1generator_function2结果: 2generator_function结果: 3123
于是有了 yield from 的语法,可以把流程控制交给子生成器,即子生成器 yield 直接切换上下文到调用者,调用者 send() 直接给子生成器发送数据。这样上面的例子可以写成:
def generator_function2():
# 正常情况应用loop.create_future()
result = yield asyncio.Future()
print('future结果:', result) return 2def generator_function():
result = yield from generator_function2()
print('generator_function2结果:', result) return 3def 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)12345678910111213141516171819202122
输出同上
但是用生成器实现协程语义上不明确,而且不能实现异步生成器(既是协程又是生成器),于是 PEP 492 提出了用 async await 作为协程语法
希望这篇文章可以帮助到你,总之同学们,IT知识尽在职坐标。