如何在Python 3.5中使用async/await?

smi*_*lar 52 python coroutine python-3.x async-await python-3.5

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import time

async def foo():
  await time.sleep(1)

foo()
Run Code Online (Sandbox Code Playgroud)

我无法使这个简单的例子运行:

RuntimeWarning: coroutine 'foo' was never awaited foo()
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 73

运行协程需要一个事件循环.使用asyncio()创建一个:

import asyncio

# Python 3.7+
asyncio.run(foo())
Run Code Online (Sandbox Code Playgroud)

要么

# Python 3.6 and older
loop = asyncio.get_event_loop()
loop.run_until_complete(foo())
Run Code Online (Sandbox Code Playgroud)

另请参阅文档的" 任务和协程"一章asyncio.如果已经有循环运行,则需要通过创建任务来同时运行其他协同程序(asyncio.create_task(...)在Python 3.7+中,asyncio.ensure_future(...)在旧版本中).

但是请注意,time.sleep()不是一个awaitable对象.它返回,None所以你在1秒后得到一个异常:

>>> asyncio.run(foo())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/.../lib/python3.7/asyncio/runners.py", line 43, in run
    return loop.run_until_complete(main)
  File "/.../lib/python3.7/asyncio/base_events.py", line 573, in run_until_complete
    return future.result()
  File "<stdin>", line 2, in foo
TypeError: object NoneType can't be used in 'await' expression
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您应该使用asyncio.sleep()协程:

async def foo():
    await asyncio.sleep(1)
Run Code Online (Sandbox Code Playgroud)

它与循环合作以使其他任务能够运行.要阻止来自没有asyncio等效项的第三方库的代码,可以在执行程序池中运行该代码.请参阅asyncio开发指南中的运行阻止代码.