Python3.x生成器yield表达式与__next__、send方法理解

当一个生成器函数被调用时,它将返回一个名为生成器迭代器。 然后这个生成器将控制生成器函数的执行。 执行过程会在这个生成器的某个方法被调用时开始。 这时,函数会执行到第一个 yield 表达式,在那里它将再次被挂起,向生成器的调用方返回 yield_list 的值,或者如果 yield_list 被省略则返回 None。————Python官方文档-6.2.9. yield 表达式

生成器函数

这是当一个带返回值的普通函数

def test_fun():
  return 1

>>print(test_fun())
1

return换成yield之后, 这个函数就变成了一个生成器函数(不是定义)

def generator_fun():
  val1 = yield 1
  val2 = yield 2

>>g = generator_fun() // 生成器函数调用时返回生成器
>>print(next(g)) // 控制生成器函数的执行
1
>>print(g.send(None)) // 控制生成器函数的执行
2

该函数被调用的时候并不直接返回yield后面的值,而是返回一个名为生成器的可迭代对象,需要使用内置函数next()或者生成器对象方法send()控制生成器函数本身的执行过程。

注意:

  • yield在函数体中可以有多个,但是函数中的return在同一分支的代码块中只能有一个
  • yield及其“返回值” 组成的整体是一个有值的表达式,被称为yield表达式,表达式的值可以从外面传入(即生成器对象send()传入的值);如果没有从外面传入,则表达式的值为None

生成器函数的开始、暂停和恢复

生成器函数的开始执行

生成器函数开始执行的方式有两种:

  1. 使用next()函数,将生成器作为参数传入:
    该函数底层会调用生成器对象内部的__next__()方法
g = generator_fun() // 生成器函数调用时返回生成器
next(g) // 生成器开始执行
  1. 使用生成器对象的send()方法,参数必须为None
g = generator_fun() // 生成器函数调用时返回生成器
g.send(None) // 生成器开始执行

生成器函数的暂停

生成器执行的特点是:执行流运行至yield时,将yield返回值返回给调用方后,函数执行的状态会被保存,然后函数执行过程被暂停

生成器函数的恢复

生成器执行恢复的方式和开始执行的调用方式相似

  1. 使用next()函数,将生成器作为参数传入:
    该函数底层会调用生成器对象内部的__next__()方法, 生成器从上一次暂停的位置继续向下执行
g = generator_fun() // 生成器函数调用时返回生成器
next(g) // 生成器从上一次暂停的位置继续执行
  1. 使用生成器对象的send()方法,参数可以是指定的值
def generator_fun():
  val1 = yield 1
  print("val1 = ", val1)
  val2 = yield 2
  print("val2 = ", val2)

>>g = test_fun() // 生成器函数调用时返回生成器
>>print(g.send(None)) // 生成器开始执行
1
>>print(g.send(2)) // 生成器继续执行,yield 1的值是传入的2, 因此, val1===2
val1 = 2
2
>>print(g.send(3)) // 生成器继续执行,yield 2的值是传入的3, 因此, val2===3
val2 = 3
StopIteration

使用send(value)传入指定值后,该值会被赋值给yield表达式, 然后复制给表达式左侧的值,最后恢复执行流,继续向下执行,直到yield返回值,或者抛出StopIteration异常。

posted @ 2025-12-11 13:34  昆仑路远  阅读(2)  评论(0)    收藏  举报