python函数之间嵌套使用yield
假设一种场景,函数 A 可以在获得函数 B 的返回值(即一个生成器对象)后,再次对其进行 yield
操作。这是因为 Python 的生成器是可迭代的,你可以在一个生成器中迭代另一个生成器,并将其结果逐个 yield
出去。
这种模式在 Python 中被称为 “生成器委托”(Generator Delegation),并且可以使用 yield from
语法来简化代码。
示例代码
方法 1:手动迭代并 yield
你可以在函数 A 中手动迭代函数 B 返回的生成器,并逐个 yield
其值:
def function_B():yield "Hello"yield "World"def function_A():generator_B = function_B() # 调用函数 B,得到一个生成器for value in generator_B:yield value # 逐个 yield 函数 B 的值# 测试
for item in function_A():print(item)
输出:
Hello
World
方法 2:使用 yield from
(推荐)
Python 提供了 yield from
语法,可以直接将一个生成器的结果委托给另一个生成器,从而避免手动迭代:
def function_B():yield "Hello"yield "World"def function_A():yield from function_B() # 使用 yield from 直接委托给函数 B# 测试
for item in function_A():print(item)
输出:
Hello
World
工作原理
-
生成器的本质:
- 当调用
function_B()
时,它不会立即执行函数体,而是返回一个生成器对象。 - 生成器对象是一个可迭代对象,每次调用
next()
时会执行到下一个yield
语句。
- 当调用
-
yield from
的作用:yield from
是一种语法糖,用于将一个生成器的结果直接委托给另一个生成器。- 它会自动处理生成器的迭代过程,并将值逐个传递给外部调用者。
-
嵌套生成器:
- 在函数 A 中,你可以嵌套多个生成器,并通过
yield
或yield from
将它们的结果逐层传递。
- 在函数 A 中,你可以嵌套多个生成器,并通过
更复杂的例子
嵌套多个生成器
假设我们有多个生成器函数,并且希望在一个顶层生成器中组合它们的结果:
def generator_1():yield "A"yield "B"def generator_2():yield "C"yield "D"def combined_generator():yield from generator_1() # 委托给 generator_1yield from generator_2() # 委托给 generator_2# 测试
for item in combined_generator():print(item)
输出:
A
B
C
D
在中间插入额外逻辑
你还可以在 yield from
的基础上插入额外的逻辑:
def generator_1():yield "A"yield "B"def generator_2():yield "C"yield "D"def combined_generator():yield "Start"yield from generator_1()yield "Middle"yield from generator_2()yield "End"# 测试
for item in combined_generator():print(item)
输出:
Start
A
B
Middle
C
D
End
注意事项
-
生成器的状态:
- 生成器是有状态的,一旦迭代完成,就不能再次迭代。如果需要重新迭代,必须重新调用生成器函数。
-
异常处理:
- 如果被委托的生成器抛出异常,异常会传播到外层生成器。你可以使用
try...except
来捕获和处理异常。
- 如果被委托的生成器抛出异常,异常会传播到外层生成器。你可以使用
-
性能优化:
- 使用
yield from
比手动迭代更高效,因为它减少了中间层的开销。
- 使用