[英]Why python3.6 could yield from a coroutine object in a non-coroutine generator?
zz.py
import asyncio
# @asyncio.coroutine
def main():
yield from asyncio.sleep(1)
next(main())
在 Python 3.6.7 中執行 --> 好的,沒有錯誤。
在 Python 3.7.3 中執行 --> NOT OK,接下來報告:
zz.py:5: RuntimeWarning: coroutine 'sleep' was never awaited yield from asyncio.sleep(1) RuntimeWarning: Enable tracemalloc to get the object allocation traceback Traceback (most recent call last): File "zz.py", line 7, in <module> next(main()) File "zz.py", line 5, in main yield from asyncio.sleep(1) TypeError: cannot 'yield from' a coroutine object in a non-coroutine generator
我知道我可以啟用@asyncio.coroutine
使兩者都工作,或者async/await
。
但是,這里我的問題是:如果我仍然使用generator
,那么 python3.6 和 python3.7 有什么區別? 我真的覺得這里很混亂。
深入python源代碼后,我找到了根本原因:
在 python3.6 中,雖然async/await
已經存在,但是coroutine.sleep
仍然使用generator based coroutine
:
@coroutine def sleep(delay, result=None, *, loop=None): """Coroutine that completes after a given time (in seconds).""" if delay == 0: yield return result if loop is None: loop = events.get_event_loop() future = loop.create_future() h = future._loop.call_later(delay, futures._set_result_unless_cancelled, future, result) try: return (yield from future) finally: h.cancel()
在python3.7中, coroutine.sleep
開始切換到native coroutine
:
async def sleep(delay, result=None, *, loop=None): """Coroutine that completes after a given time (in seconds).""" if delay <= 0: await __sleep0() return result if loop is None: loop = events.get_event_loop() future = loop.create_future() h = loop.call_later(delay, futures._set_result_unless_cancelled, future, result) try: return await future finally: h.cancel()
所以,當python3.6 yield from asyncio.sleep(1)
執行yield from asyncio.sleep(1)
時,它實際上並沒有從原生協程中yield,肯定沒有錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.