Python生成器(yield)工作原理详解

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Python生成器是一种强大的机制,用于高效处理数据序列。它们可以按需计算值,从而显著节省系统内存。生成器的核心是yield关键字,它与传统的return有着本质区别。

Python生成器基础

生成器是特殊的函数,它们返回迭代器而非具体值。主要区别在于使用yield关键字,它能在函数调用之间保存状态。

每次调用生成器函数时,执行会从上次yield语句停止的地方继续。这使得生成器成为处理大数据流的理想方案,无需将所有数据加载到内存中。

def simple_generator():
    yield 1
    yield 2
    yield 3

gen = simple_generator()
for value in gen:
    print(value)

执行结果:

1
2
3

yield关键字的工作原理

yield关键字遵循"惰性求值"原则:

  1. 首次调用next()时,从函数开头执行到第一个yield
  2. 返回值后,函数"冻结"其当前状态
  3. 再次调用next()时,从停止处继续执行
  4. 此过程持续到函数结束
def counter():
    print("生成器开始")
    yield 1
    print("第一个yield之后")
    yield 2
    print("第二个yield之后")

gen = counter()
next(gen)  # 输出:生成器开始
next(gen)  # 输出:第一个yield之后

生成器对比列表的优势

在处理大量数据时,使用生成器而非列表具有显著优势:

节省内存:生成器不会一次性存储所有值,而是按需生成。

# 列表 - 占用大量内存
squares_list = [x * x for x in range(1000000)]

# 生成器 - 内存消耗极小
squares_gen = (x * x for x in range(1000000))

性能提升:生成器能立即返回值,无需等待完整序列生成完毕。

创建无限序列

生成器可以创建无限序列而无需担心内存溢出:

def infinite_counter(start=0):
    while True:
        yield start
        start += 1

counter = infinite_counter()
print(next(counter))  # 0
print(next(counter))  # 1
print(next(counter))  # 2

生成器的高级方法

生成器支持几个专用方法:

next() — 获取生成器的下一个值 send(value) — 向生成器内部发送值 throw() — 在生成器内部引发异常 close() — 强制停止生成器

def interactive_generator():
    value = yield "开始"
    while True:
        value = yield f"收到: {value}"

gen = interactive_generator()
print(next(gen))           # 开始
print(gen.send(42))        # 收到: 42
print(gen.send("你好"))    # 收到: 你好

生成器中的异常处理

生成器支持异常处理机制,包括特殊的GeneratorExit异常:

def example_generator():
    try:
        yield 1
        yield 2
    except GeneratorExit:
        print("生成器已关闭!")

gen = example_generator()
print(ne                

博客

书籍推荐