跳转至

5. 定义、创建和运行协程

5. Define, Create and Run Coroutines

我们可以在 Python 程序中定义协程,就像定义新的子例程(函数)一样。

一旦定义,协程函数就可以用来创建协程对象。

“asyncio”模块提供了在事件循环中运行协程对象的工具,事件循环是协程的运行时。

We can define coroutines in our Python programs, just like defining new subroutines (functions).

Once defined, a coroutine function can be used to create a coroutine object.

The “asyncio” module provides tools to run our coroutine objects in an event loop, which is a runtime for coroutines.

5.1 如何定义协程

5.1 How to Define a Coroutine

协程可以通过 “async def” 表达式来定义。

这是用于定义子例程的 “def” 表达式的扩展。

它定义了一个可以创建的协程并返回一个协程对象。

例如:

# 定义一个协程
async def custom_coro():
    # ...

使用 “async def” 表达式定义的协程被称为“协程函数”。

协程函数:返回协程对象的函数。 协程函数可以使用 async def 语句来定义,并且可以包含await、async for 和async with 关键字。

PYTHON GLOSSARY

然后,协程可以在其中使用协程特定的表达式,例如 awaitasync forasync with

Python 协程的执行可以在许多点暂停和恢复(请参阅协程)。 wait 表达式、async for 和 async with 只能在协程函数体中使用。

COROUTINE FUNCTION DEFINITION

例如:

# 定义一个协程
async def custom_coro():
    # 等待另一个协程
    await asyncio.sleep(1)

A coroutine can be defined via the “async def” expression.

This is an extension of the “def” expression for defining subroutines.

It defines a coroutine that can be created and returns a coroutine object.

For example:

# define a coroutine
async def custom_coro():
    # ...

A coroutine defined with the “async def” expression is referred to as a “coroutine function“.

coroutine function: A function which returns a coroutine object. A coroutine function may be defined with the async def statement, and may contain await, async for, and async with keywords.

— PYTHON GLOSSARY

A coroutine can then use coroutine-specific expressions within it, such as await, async for, and async with.

Execution of Python coroutines can be suspended and resumed at many points (see coroutine). await expressions, async for and async with can only be used in the body of a coroutine function.

— COROUTINE FUNCTION DEFINITION

For example:

# define a coroutine
async def custom_coro():
    # await another coroutine
    await asyncio.sleep(1)

5.2 如何创建协程

5.2 How to Create a Coroutine

一旦定义了协程,就可以创建它。

这看起来就像调用一个子例程。

例如:

...
# 创建一个协程
coro = custom_coro()

这不会执行协程。

它返回一个“coroutine”对象

您可以将协程函数视为协程对象的工厂; 更直接地,请记住调用协程函数不会导致任何用户编写的代码执行,而只是构建并返回一个协程对象。

— PAGE 516, PYTHON IN A NUTSHELL, 2017.

“协程” Python 对象具有方法,例如 send()close()。 它是一种类型。

我们可以通过创建协程实例并调用 type() 内置函数来报告其类型来演示这一点。

例如:

# SuperFastPython.com
# 检查协程的类型

# 定义协程
async def custom_coro():
    # 等待另一个协程
    await asyncio.sleep(1)

# 创建协程
coro = custom_coro()
# 检查协程的类型
print(type(coro))

运行示例报告创建的协程是一个“协程”类。

我们还会得到一个运行时错误,因为协程已创建但从未执行,我们将在下一节中探讨这一点。

<class 'coroutine'>
sys:1: RuntimeWarning: coroutine 'custom_coro' was never awaited

协程对象是一个等待对象。

这意味着它是实现 __await__() 方法的 Python 类型。

可等待对象通常实现 __await__() 方法。 从 async def 函数返回的协程对象是可等待的。

AWAITABLE OBJECTS

您可以在教程中了解有关可等待的更多信息:

Once a coroutine is defined, it can be created.

This looks like calling a subroutine.

For example:

...
# create a coroutine
coro = custom_coro()

This does not execute the coroutine.

It returns a “coroutine” object.

You can think of a coroutine function as a factory for coroutine objects; more directly, remember that calling a coroutine function does not cause any user-written code to execute, but rather just builds and returns a coroutine object.

— PAGE 516, PYTHON IN A NUTSHELL, 2017.

A “coroutine” Python object has methods, such as send() and close(). It is a type.

We can demonstrate this by creating an instance of a coroutine and calling the type() built-in function in order to report its type.

For example:

# SuperFastPython.com
# check the type of a coroutine

# define a coroutine
async def custom_coro():
    # await another coroutine
    await asyncio.sleep(1)

# create the coroutine
coro = custom_coro()
# check the type of the coroutine
print(type(coro))

Running the example reports that the created coroutine is a “coroutine” class.

We also get a RuntimeError because the coroutine was created but never executed, we will explore that in the next section.

<class 'coroutine'>
sys:1: RuntimeWarning: coroutine 'custom_coro' was never awaited

A coroutine object is an awaitable.

This means it is a Python type that implements the __await__() method.

An awaitable object generally implements an __await__() method. Coroutine objects returned from async def functions are awaitable.

AWAITABLE OBJECTS

You can learn more about awaitables in the tutorial:

5.3 Python中如何运行协程

5.3 How to Run a Coroutine From Python

可以定义和创建协程,但它们只能在事件循环内执行。

事件循环是每个异步应用程序的核心。 事件循环运行异步任务和回调、执行网络 IO 操作并运行子进程。

ASYNCIO EVENT LOOP

执行协程的事件循环管理协程之间的协作多任务处理。

协程对象只能在事件循环运行时运行。

— PAGE 517, PYTHON IN A NUTSHELL, 2017.

启动协程事件循环的典型方法是通过 asyncio.run() 函数。

该函数采用一个协程并返回该协程的值。 提供的协程可以用作基于协程的程序的入口点。

例如:

# SuperFastPython.com
# 运行协程的示例
import asyncio
# 定义一个协程
async def custom_coro():
    # 等待另一个协程
    await asyncio.sleep(1)

# 主协程
async def main():
    # 执行我的自定义协程
    await custom_coro()

# 启动协程程序
asyncio.run(main())

现在我们知道如何定义、创建和运行协程,让我们花点时间来了解事件循环。

Coroutines can be defined and created, but they can only be executed within an event loop.

The event loop is the core of every asyncio application. Event loops run asynchronous tasks and callbacks, perform network IO operations, and run subprocesses.

ASYNCIO EVENT LOOP

The event loop that executes coroutines, manages the cooperative multitasking between coroutines.

Coroutine objects can only run when the event loop is running.

— PAGE 517, PYTHON IN A NUTSHELL, 2017.

The typical way to start a coroutine event loop is via the asyncio.run() function.

This function takes one coroutine and returns the value of the coroutine. The provided coroutine can be used as the entry point into the coroutine-based program.

For example:

# SuperFastPython.com
# example of running a coroutine
import asyncio
# define a coroutine
async def custom_coro():
    # await another coroutine
    await asyncio.sleep(1)

# main coroutine
async def main():
    # execute my custom coroutine
    await custom_coro()

# start the coroutine program
asyncio.run(main())

```

Now that we know how to define, create, and run a coroutine, let’s take a moment to understand the event loop.


最后更新: 2024年9月4日
创建日期: 2024年9月4日