AIGC标识 yield 五大用法总结

  1. 上下文管理器 (@contextmanager)
    将函数体一分为二,yield 前获取资源,yield 后释放资源。
点击查看代码
from contextlib import contextmanager

@contextmanager
def managed_resource():
    print(">>> 获取资源")
    resource = {"status": "connected"}
    try:
        yield resource          # 暂停,将 resource 传给 with ... as var
    finally:
        print(">>> 释放资源")   # 无论 with 块是否异常,必定执行

# 使用
with managed_resource() as r:
    print(f"使用资源: {r}")
# 输出:
# >>> 获取资源
# 使用资源: {'status': 'connected'}
# >>> 释放资源
  1. 惰性生成器
    按需产出值,不一次性加载全部数据到内存。
点击查看代码
def read_large_file(path):
    with open(path) as f:
        for line in f:
            yield line.strip()  # 每次只产出一行,内存占用恒定

# 消费时逐个获取,而非全部读入列表
for line in read_large_file("10GB_log.txt"):
    process(line)
  1. 协程 / 双向通信 (send)
    yield 既向外产出值,又接收外部传入的值。
点击查看代码
def accumulator():
    total = 0
    while True:
        value = yield total     # ① 产出 total;② 接收 send() 传入的 value
        total += value

acc = accumulator()
next(acc)           # 必须先 next() 启动,走到第一个 yield → 返回 0
print(acc.send(10)) # 传入 10, total=10 → 打印 10
print(acc.send(20)) # 传入 20, total=30 → 打印 30
  1. 委托生成器 (yield from)
    将子生成器的产出和双向通信协议透明转发,消除嵌套循环。
点击查看代码
def flatten(nested):
    for item in nested:
        if isinstance(item, list):
            yield from flatten(item)  # 递归委托,自动透传 send/throw/close
        else:
            yield item

print(list(flatten([1, [2, [3, 4]], 5])))
# → [1, 2, 3, 4, 5]
  1. 类迭代协议 (iter)
    在类的 iter 中使用 yield,让自定义对象直接支持 for 循环。
点击查看代码
class Range:
    def __init__(self, start, stop):
        self.start = start
        self.stop = stop

    def __iter__(self):
        current = self.start
        while current < self.stop:
            yield current       # 使实例可直接 for 循环,无需手写 __next__
            current += 1

for n in Range(3, 7):
    print(n)  # 3, 4, 5, 6
用法 关键语法 数据流向 核心价值 典型场景
1. 上下文管理器 @contextmanager + yield 单向产出(资源句柄) 将函数体一分为二,前半部分获取资源(__enter__),后半部分释放资源(__exit__),保证清理逻辑必执行 SSH隧道、数据库连接、文件锁、临时环境变量切换
2. 惰性生成器 yield value 单向产出 按需计算,内存复杂度从 O(n) 降为 O(1),支持无限序列 读取超大文件、流式API响应、数据管道(Pipeline)
3. 协程(双向通信) var = yield value + .send() 双向收发 函数可暂停并接收外部注入的值,实现协作式并发与状态保持 生产者-消费者模型、状态机、旧版异步框架(如Scrapy/Tornado)
4. 委托生成器 yield from sub_gen 双向透传 自动将子生成器的产出及 send()/throw()/close() 协议透明转发,消除嵌套循环 递归展平嵌套结构、组合多个数据源、asyncio底层实现
5. 类迭代协议 __iter__yield 单向产出 替代繁琐的 __next__ + StopIteration 三件套,让自定义对象天然支持 for 循环且具备惰性 自定义集合类、树/图遍历、分页查询对象
posted @ 2026-09-10 10:15  不知者buwei  阅读(0)  评论(0)    收藏  举报