あなたのコードは、次のエラーを生成します。
...
yield from a() # <=========== only 1 tiny change
TypeError: cannot 'yield from' a coroutine object in a non-coroutine generator
は明らかなようにasyncioを使用しているとき、あなたはコルーチンをマークする@coroutine
またはasync def
を使用する必要がありますいずれか、エラーメッセージに記載されています。
import asyncio
async def a():
print('hello')
async def b():
await a()
loop = asyncio.get_event_loop()
loop.run_until_complete(b())
loop.close()
print('done')
または、Pythonの3.4のために:async def
秒で、await
ではなくyield from
の使用すべきである
import asyncio
@asyncio.coroutine
def a():
print('hello')
@asyncio.coroutine
def b():
yield from a()
loop = asyncio.get_event_loop()
loop.run_until_complete(b())
loop.close()
print('done')
あなたの最初の例は、 "バグだらけ" と考えられているが、run_until_complete
ので、それは "適切に" 実行されていますiscoroutine
は、現在、発電機(def
はyield
/yield from
となります)に対してTrueを返しますが、これは将来のバージョンのPythonで変更される可能性のある実装の詳細です。 (async def a()
の代わりに)def a()
に@couroutine
を使用するか、またはdef a()
にyield from asyncio.sleep(1)
を追加するだけで、2番目の例も実行されます。 asyncioでコルーチンとしてマークされていないジェネレータを使用しているときは、現在Pythonは "慈悲深い"かもしれませんが、async defs
を使用しているときはそうではありません。
出典
2017-01-17 08:36:39
Udi
ありがとうございます@udiここに興味のある別のパズルがあります:http://stackoverflow.com/questions/41708609/unfair-scheduling-bad-lock-optimization-in-asyncio-event-loop – user2297550