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

时间:2015-09-27 14:19:35

标签: python python-3.x async-await coroutine python-3.5

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

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

foo()

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

RuntimeWarning: coroutine 'foo' was never awaited foo()

2 个答案:

答案 0 :(得分:69)

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

import asyncio

# Python 3.7+
asyncio.run(foo())

# Python 3.6 and older
loop = asyncio.get_event_loop()
loop.run_until_complete(foo())

另见Tasks and Coroutines chapter of the asyncio documentation。如果您已经有循环运行,那么您希望通过创建任务({3}在Python 3.7 +中,asyncio.create_task(...)在旧版本中)同时运行其他协同程序。

但请注意,asyncio.ensure_future(...) 不是等待对象。它返回time.sleep(),因此您在1秒后得到异常:

None

在这种情况下,您应该使用asyncio.sleep() coroutine代替:

>>> 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

与循环合作以启用其他任务。要阻止来自没有asyncio等效项的第三方库的代码,您可以在executor pool中运行该代码。请参阅asyncio开发指南中的Running Blocking Code

答案 1 :(得分:2)

如果您已经在运行循环(包含其他一些任务),则可以使用以下命令添加新任务:

asyncio.ensure_future(foo())

否则你可能会得到

The event loop is already running

错误。