CS61A Day3 yield

yield 关键字

带有yield关键字的函数称为生成器(generator), 有以下代码:

def fab(max): 
    n, a, b = 0, 0, 1 
    while n < max: 
        yield b      # 使用 yield
        # print b 
        a, b = b, a + b 
        n = n + 1
 
for n in fab(5): 
    print(n)

首先yield起到return的作用, 使函数终止并返回值. 但和return有一点不同, return后函数终止并且销毁局部变量; 而yield返回可迭代的generator(生成器)对象. 即在下一次运行该生成器对象时, 从yield的下一行继续执行, 直到yield.


上面的代码是斐波那契的yield写法, 通过简述其执行过程, 可以大致理解yield的作用.


在for循环中, 调用fab(5)并不会执行函数,而是返回的迭代器(iterable)或者生成器. 在循环中, 第一次迭代执行到yield b, 返回b的值, 下一次迭代从yield的下一行a, b = b, a + b开始执行, 直到再一个yield b.
输出结果为:
输出结果

yield 相关方法

  • next( )
>>>f = fab(5) 
>>> f.next() 
1 
>>> f.next() 
1 
>>> f.next() 
2 
>>> f.next() 
3 
>>> f.next() 
5 
>>> f.next() 
Traceback (most recent call last): 
 File "<stdin>", line 1, in <module> 
StopIteration

对generator(生成器)调用next( ), 过程和结果如上.


f 是返回的可迭代的生成器对象, next( )是对函数进行一次执行, 类似上面的一次迭代.

  • send( )
    有以下代码:
def foo():
    print("starting...")
    while True:
        res = yield 4
        print("res:",res)
g = foo()
print(next(g))
print("*"*20)
print(g.send(7))

输出结果:  
starting...
4
********************
res: 7
4

由于yield会直接返回4并终止此次迭代, 在下一次迭代时res由于并没有成功赋值, 所以print出来的是None.


send( )方法就是用参数替代原本yield的地方, 所以在*线之下, res被赋值为7.

参考资料


CS61A Day3 yield
http://zqizhang.github.io/2022/02/23/CS61A-Day3/
作者
Wang Xun
发布于
2022年2月23日
许可协议