深入解析 Python 中 yield 实现异步协作的原理

今天早睡
今天早睡
发布时间:2026-10-12| 2人浏览过
原创

本文深入解析 Python 中 yield 关键字在异步编程中的应用。通过剖析生成器的 send() 方法,详细阐述 yield 如何挂起与恢复执行、接收参数及返回值,从而模拟异步协作流程。同时结合简单调度器示例,解释基于事件循环的异步模型运行机制,帮助开发者理解 Python 异步操作的底层逻辑。

初学 Python 时,yield 关键字往往令人感到困惑。理解其核心作用对于掌握高级特性至关重要,主要功能包括:

① 返回当前计算结果;② 接收来自调用者通过 send() 传递的参数。

为了更清晰地理解这一机制,我们分析以下代码示例:

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

def consumer():
  r = ''
  while True:
    n = yield r
    print("[Consumer] n = %d" %n)
    if not n:
      return
    print("[Consumer] consuming %s..." %n)
    r = '200 OK'

def produce(c):
  c.send(None)
  h = 0
  while h < 5:
    h = h + 1
    print("[Producer] producing %d..." %h)
    s = c.send(h)
    print("[Producer] consumer return: %s" %s)
  c.close()

c = consumer() #创建一个生成器
produce(c) #在该函数中,调用生成器的send()方法

结合程序的执行流程,可以得出以下运行逻辑:

第一步:

在 produce(c) 函数内部,首先调用 c.send(None) 来启动生成器。此时程序执行至 yield 语句处暂停。随后,produce() 函数继续执行后续代码。从运行结果可以看出,确实打印了 [Produce] producing 1 …。当程序执行到 c.send(h) 时,通过 yield 将参数(h = 1)传递给 consumer() 函数,从而进入 consumer() 的执行上下文。

第二步:

yield 将传递的参数(h=1)赋值给 consumer() 函数中的变量 n,并接着上一次暂停的位置继续执行。此时打印出 [Consumer] n = 1,[Consumer] consuming 1…。在 consumer() 函数内部,变量 r 被赋值为 '200 OK'。接着循环遇到 yield,consumer() 函数再次暂停,并将变量 r 的值返回。此时控制权交还,程序重新进入 produce(c) 函数继续执行。

第三步:

produce(c) 函数接着从第一步中 c.send(h) 的位置继续向下执行,打印出 [Producer] consumer return: 200 OK。随后进入下一轮循环,打印 [Producer] producing 2…,并再次调用 c.send(h) …。如此循环往复,回到第一步的逻辑,直到满足终止条件。

补充知识:Python asyncio 模型中的事件循环机制

异步编程的核心基础是事件循环。

简单来说,事件循环的工作流程如下:

1. 将待执行的函数或任务放入队列;

2. 从队列中取出函数并执行;

3. 检查该函数是否还需要继续执行(例如是否有新的任务生成);

4. 若需继续,则重复第一步。

以下是一个简单的示例说明:

"""
  1.yield 挂起当前函数.
  2.使用调度器循环
  3.使用next唤醒此函数继续执行
"""
def f1():
  for i in range(3):
    print('f1 %d'%i)
    yield
def f2():
  for i in range(5):
    print('f2 %d' %i)
    yield
def f3():
  for i in range(10):
    print('f3 %d'%i)
    yield
#模拟一个调度器
task_q = collections.deque((f1(),f2(),f3()))
#让调度器调度这些生成器们
while task_q:
  task = task_q.popleft() #弹出首个生成器
  try:
    next(task)     #执行,如果没有异常证明此生成器还没执行完成,可以继续放入队列中
    task_q.append(task) #执行完成后,把任务继续添加到队列中.
    time.sleep(0.5)
  except StopIteration as ex:
    pass

以上关于 Python 中由 yield 实现异步操作的解析就是全部内容,希望能对大家理解生成器与异步协作有所帮助,欢迎参考与支持。

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。