Python Academy · 课时

yield 关键字

使用 yield 编写生成器函数,创建自定义迭代器。

第 4 / 4 课14 个步骤

yield 关键字 是 CoddyKit 上的免费 Python Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Python Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Python Academy 课程共包含 4 节课。

简介

生成器函数使用 yield 以惰性方式生成一系列值,并在每次 yield 之间暂停执行。

什么是 yield?

包含 yield 的函数就是生成器函数。每次调用 next() 时,都会从上一次 yield 的位置继续执行。
def count_up(n):
    for i in range(n):
        yield i
for x in count_up(3):
    print(x)

生成器函数与普通函数

调用生成器函数会返回一个生成器对象,此时不会运行任何代码。代码会在遍历生成器时执行。
def gen():
    print('start')
    yield 1
    print('middle')
    yield 2
g = gen()  # no print yet
print(next(g))  # 'start', then 1

无限生成器

def naturals(n=0): while True: yield n; n+=1 是一个无限序列。请与 islice 或 break 配合使用。
def naturals(n=0):
    while True:
        yield n
        n += 1
import itertools
print(list(itertools.islice(naturals(), 5)))

yield from

yield from sub_gen() 会将执行委托给子生成器,转发所有值。它等价于 for x in sub: yield x。
def chain(*iters):
    for it in iters:
        yield from it
print(list(chain([1,2], [3,4], [5])))

使用 send() 发送值

gen.send(value) 会恢复生成器,并传入一个值,该值会成为 yield 表达式的结果。
def accumulator():
    total = 0
    while True:
        n = yield total
        if n is None: break
        total += n
g = accumulator()
next(g)  # prime
print(g.send(10))
print(g.send(5))

生成器状态

生成器会在每个 yield 处暂停,并在调用之间保留局部变量,因此它天然适合实现协程。
def stateful():
    seen = set()
    while True:
        item = yield
        seen.add(item)
        yield len(seen)
g = stateful()
next(g); g.send('a'); print(next(g)); g.send('b'); print(next(g))

关闭生成器

gen.close() 会在生成器内部引发 GeneratorExit。请在生成器内部使用 try/finally 执行清理。
def resource_gen():
    try:
        while True:
            yield
    finally:
        print('cleaned up')
g = resource_gen()
next(g)
g.close()

StopIteration 与 return

生成器中的 return value 会设置 StopIteration 异常的 value 属性。yield from 会使用该属性获取返回值。
def gen_with_return():
    yield 1
    yield 2
    return 'done'
g = gen_with_return()
try:
    while True: print(next(g))
except StopIteration as e:
    print('returned:', e.value)

斐波那契生成器

生成器非常适合生成无限数学序列:yield a; a, b = b, a+b
def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b
import itertools
print(list(itertools.islice(fibonacci(), 10)))

生成器与使用 __iter__ 的类

生成器比编写包含 __iter__ 和 __next__ 的类更简单。对于直接的序列,请使用生成器。
# Generator is simpler than:
# class Counter:
#     def __iter__(self): return self
#     def __next__(self): ...
print('generators simplify iterators')

快速检查

在生成器函数中,yield from sub() 的作用是什么?

回顾

yield 会暂停生成器函数。生成器函数会返回生成器对象。yield from 会将控制权委托给子生成器。send() 会传入值。close() 会触发清理操作。

继续学习

太棒了!请继续下一课,以进一步提升您的技能。
免费开始

用 AI 导师学习 Python — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
76
课程
320

常见问题解答

「yield 关键字」课时是免费的吗?

是的 — 「yield 关键字」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Python Academy 课程的其余内容,请升级到 CoddyKit PRO。 Python Academy 课程共包含 4 节课。

「yield 关键字」这节课中我会学到什么?

使用 yield 编写生成器函数,创建自定义迭代器。 你通过在浏览器中直接运行的动手代码来练习 Python Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Python Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Python Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「yield 关键字」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Python Academy 课中编写并运行代码吗?

能。每节 Python Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 列表推导式
  2. 集合与字典推导式
  3. 生成器表达式
  4. yield 关键字
← 返回 Python Academy