8.8. 协程

3.5 新版功能.

8.8.1. 协程函数定义

  1. async_funcdef ::= [decorators] "async" "def" funcname "(" [parameter_list] ")"
  2. ["->" expression] ":" suite

Python 协程可以在多个位置上挂起和恢复执行 (参见 coroutine)。 在协程函数体内部,awaitasync 标识符已成为保留关键字;await 表达式,async for 以及 async with 只能在协程函数体中使用。

使用 async def 语法定义的函数总是为协程函数,即使它们不包含 awaitasync 关键字。

在协程函数体中使用 yield from 表达式将引发 SyntaxError

协程函数的例子:

  1. async def func(param1, param2):
  2. do_stuff()
  3. await some_coroutine()

8.8.2. async for 语句

  1. async_for_stmt ::= "async" for_stmt

asynchronous iterable 能够在其 iter 实现中调用异步代码,而 asynchronous iterator 可以在其 next 方法中调用异步代码。

async for 语句允许方便地对异步迭代器进行迭代。

以下代码:

  1. async for TARGET in ITER:
  2. SUITE
  3. else:
  4. SUITE2

在语义上等价于:

  1. iter = (ITER)
  2. iter = type(iter).__aiter__(iter)
  3. running = True
  4. while running:
  5. try:
  6. TARGET = await type(iter).__anext__(iter)
  7. except StopAsyncIteration:
  8. running = False
  9. else:
  10. SUITE
  11. else:
  12. SUITE2

另请参阅 __aiter__()__anext__() 了解详情。

在协程函数体之外使用 async for 语句将引发 SyntaxError

8.8.3. async with 语句

  1. async_with_stmt ::= "async" with_stmt

asynchronous context manager 是一种 context manager,能够在其 enterexit 方法中暂停执行。

以下代码:

  1. async with EXPRESSION as TARGET:
  2. SUITE

在语义上等价于:

  1. manager = (EXPRESSION)
  2. aenter = type(manager).__aenter__
  3. aexit = type(manager).__aexit__
  4. value = await aenter(manager)
  5. hit_except = False
  6. try:
  7. TARGET = value
  8. SUITE
  9. except:
  10. hit_except = True
  11. if not await aexit(manager, *sys.exc_info()):
  12. raise
  13. finally:
  14. if not hit_except:
  15. await aexit(manager, None, None, None)

另请参阅 __aenter__()__aexit__() 了解详情。

在协程函数体之外使用 async with 语句将引发 SyntaxError

参见

PEP 492 - 使用 async 和 await 语法实现协程

将协程作为 Python 中的一个正式的单独概念,并增加相应的支持语法。

脚注

1

异常会被传播给发起调用栈,除非存在一个 finally 子句正好引发了另一个异常。 新引发的异常将导致旧异常的丢失。

2

作为函数体的第一条语句出现的字符串字面值会被转换为函数的 __doc__ 属性,也就是该函数的 docstring

3

作为类体的第一条语句出现的字符串字面值会被转换为命名空间的 __doc__ 条目,也就是该类的 docstring