8.8. 协程
3.5 新版功能.
8.8.1. 协程函数定义
- async_funcdef ::= [
decorators
] "async" "def"funcname
"(" [parameter_list
] ")"- ["->"
expression
] ":"suite
Python 协程可以在多个位置上挂起和恢复执行 (参见 coroutine)。 在协程函数体内部,await
和 async
标识符已成为保留关键字;await
表达式,async for
以及 async with
只能在协程函数体中使用。
使用 async def
语法定义的函数总是为协程函数,即使它们不包含 await
或 async
关键字。
在协程函数体中使用 yield from
表达式将引发 SyntaxError
。
协程函数的例子:
async def func(param1, param2):
do_stuff()
await some_coroutine()
8.8.2. async for
语句
- async_for_stmt ::= "async"
for_stmt
asynchronous iterable 能够在其 iter 实现中调用异步代码,而 asynchronous iterator 可以在其 next 方法中调用异步代码。
async for
语句允许方便地对异步迭代器进行迭代。
以下代码:
async for TARGET in ITER:
SUITE
else:
SUITE2
在语义上等价于:
iter = (ITER)
iter = type(iter).__aiter__(iter)
running = True
while running:
try:
TARGET = await type(iter).__anext__(iter)
except StopAsyncIteration:
running = False
else:
SUITE
else:
SUITE2
另请参阅 __aiter__()
和 __anext__()
了解详情。
在协程函数体之外使用 async for
语句将引发 SyntaxError
。
8.8.3. async with
语句
- async_with_stmt ::= "async"
with_stmt
asynchronous context manager 是一种 context manager,能够在其 enter 和 exit 方法中暂停执行。
以下代码:
async with EXPRESSION as TARGET:
SUITE
在语义上等价于:
manager = (EXPRESSION)
aenter = type(manager).__aenter__
aexit = type(manager).__aexit__
value = await aenter(manager)
hit_except = False
try:
TARGET = value
SUITE
except:
hit_except = True
if not await aexit(manager, *sys.exc_info()):
raise
finally:
if not hit_except:
await aexit(manager, None, None, None)
另请参阅 __aenter__()
和 __aexit__()
了解详情。
在协程函数体之外使用 async with
语句将引发 SyntaxError
。
参见
PEP 492 - 使用 async 和 await 语法实现协程
将协程作为 Python 中的一个正式的单独概念,并增加相应的支持语法。
脚注
异常会被传播给发起调用栈,除非存在一个 finally
子句正好引发了另一个异常。 新引发的异常将导致旧异常的丢失。
作为函数体的第一条语句出现的字符串字面值会被转换为函数的 __doc__
属性,也就是该函数的 docstring。
作为类体的第一条语句出现的字符串字面值会被转换为命名空间的 __doc__
条目,也就是该类的 docstring。