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

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

foo()

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

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

2 回答 2

77

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

import asyncio

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

或者

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

另请参阅文档的任务和协程章节asyncio。如果您已经运行了一个循环,您可能希望通过创建一个任务来同时运行其他协程(asyncio.create_task(...)在 Python 3.7+ 中,asyncio.ensure_future(...)在旧版本中)。

但是请注意,这不是time.sleep()一个可等待的对象。它会返回,因此您会在 1 秒后收到异常:None

>>> 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.sleep()协程

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

它与循环配合以使其他任务能够运行。对于阻止来自没有 asyncio 等效项的第三方库的代码,您可以在executor pool中运行该代码。请参阅asyncio 开发指南中的运行阻塞代码

于 2015-09-27T14:25:00.247 回答
3

如果您已经有一个循环正在运行(以及其他一些任务),您可以添加新任务:

asyncio.ensure_future(foo())

否则你可能会得到

The event loop is already running

错误。

于 2018-05-09T13:06:49.393 回答