簡體   English   中英

為什么python3.6可以從非協程生成器中的協程對象產生?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM