Я только что заметил что-то удивительное.Рассмотрим следующий пример:
import asyncio
async def wait_n(n):
asyncio.sleep(n)
async def main(fn):
print("meh")
await fn(1)
print("foo")
loop = asyncio.get_event_loop()
loop.run_until_complete(main(wait_n))
Когда мы запустим это, мы по праву получим следующее предупреждение:
awaitable_lambda.py:5: RuntimeWarning: coroutine 'sleep' was never awaited
asyncio.sleep (n)
Это потому, чтов wait_n
мы назвали asyncio.sleep(n)
без await
.
Но теперь рассмотрим второй пример:
import asyncio
async def main(fn):
print("meh")
await fn(1)
print("foo")
loop = asyncio.get_event_loop()
loop.run_until_complete(main(lambda n: asyncio.sleep(n)))
На этот раз мы используем lambda
и на удивление код работаетпросто отлично, хотя нет await
.
Я понимаю, что мы не можем использовать await
внутри выражения Python lambda
, так что это похоже на функцию улучшения эргономики, ноэто вызывает у меня несколько вопросов:
- Как именно это работает?Означает ли это простое «введение»
await
перед любой функцией сопрограммы? - Это где-то задокументировано (PEP)?
- Есть ли другие последствия этого?Можем ли мы просто безопасно вызывать функции сопрограммы из лямбда-выражений и полагаться на Python, который нас ждет?