Max*_*Tet 10 python-3.x python-asyncio
想象一下以下非常常见的情况:您编写了一个冗长而复杂的函数,并意识到应该将一些代码提取到一个单独的函数中以便重用和/或可读.通常,这个额外的函数调用不会改变程序的语义.
但是,现在假设您的函数是一个协程,并且您要提取的代码包含至少一个异步调用.将它提取到一个单独的函数现在突然改变你的程序语义,方法是插入一个新的协同程序产生的点,事件循环控制,并且可以在其间安排任何其他协程.
以前的例子:
async def complicated_func():
foo()
bar()
await baz()
Run Code Online (Sandbox Code Playgroud)
示例之后:
async def complicated_func():
foo()
await extracted_func()
async def extracted_func():
bar()
await baz()
Run Code Online (Sandbox Code Playgroud)
在之前的示例中,complicated_func保证不会在呼叫foo()和呼叫之间暂停bar().重构后,此保证将丢失.
我的问题是:是否有可能调用extracted_func()它立即执行,好像它的代码是内联的?或者是否有其他方法可以在不更改程序语义的情况下执行此类常见的重构任务?
重构后,此保证将丢失.
实际上并非如此.
是否可以调用extracted_func()使其立即执行,就像它的代码是内联的一样?
情况已经如此.
await some_coroutine()意味着some_coroutine可能会将控制权交还给事件循环,但在实际等待未来(例如某些I/O操作)之前,它不会这样做.
考虑这个例子:
import asyncio
async def coro():
print(1)
await asyncio.sleep(0)
print(3)
async def main():
loop.call_soon(print, 2)
await coro()
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Run Code Online (Sandbox Code Playgroud)
注意如何2在预期之间1和3预期之间打印.
这也意味着可以通过编写这样的代码来冻结事件循环:
async def coro():
return
async def main():
while True:
await coro()
Run Code Online (Sandbox Code Playgroud)
在这种情况下,事件循环永远不会有机会运行另一个任务.
| 归档时间: |
|
| 查看次数: |
4112 次 |
| 最近记录: |