繁体   English   中英

python生成器中产量的确切返回点

[英]Exact return point of yield in python generators

为了自学Python生成器,尤其是它们的send()方法,我想写一个玩具示例,让我计算一个“可中断的”斐波那契序列。

最终我成功了,但是我不知道到底发生了什么。 考虑这两个例子。

成功的例子:

def genFib(a=0, b=1):
    while True:
        c = yield a+b
        if c:
            a, b = b, c
        else:
            a, b = b, a+b
    return
​
fib_number = genFib()
​
print fib_number.next()
print fib_number.next()
print fib_number.next()
print fib_number.next()
print fib_number.next()
print fib_number.send(100)
print fib_number.next()
print fib_number.next()
​
1
2
3
5
8
105
205
310

我认为可以解决的失败:

def genFib(a=0, b=1):
    while True:
        c = yield a+b
        a, b = b, c
    return
​
fib_number = genFib()
​
print fib_number.next()
print fib_number.next()
1
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-59-4513153ea517> in <module>()
      8 
      9 print fib_number.next()
---> 10 print fib_number.next()

<ipython-input-59-4513153ea517> in genFib(a, b)
      1 def genFib(a=0, b=1):
      2     while True:
----> 3         c = yield a+b
      4         a, b = b, c
      5     return

TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'

为什么第二个示例不起作用? 特别是,第二个示例似乎在生成器的第一次执行之外的所有其他操作中为c分配了None值。 为什么? 如何知道第一次调用next()而不是下next()时分配给c

我的理解是,生成器从屈服线之后的行开始恢复执行(当再次调用它们时),但是我的示例让我认为这是错误的,至少在某些情况下是这样。 执行从何处恢复? 它会重新执行yield线,但是这次以某种方式放弃了yield后的所有内容吗? c如何分配给None

yield有点奇怪。 在评估右侧之后但在分配发生之前,执行会在yield处暂停。

yield语句中返回的值是您.send给生成器的任何.send 由于您正在调用.next而不是.send ,因此yield表达式( c )返回的值为None 在第一个示例中,这很好,因为会检查c的真实性,然后在它为假的情况下不使用它(例如None )。 但是,在第二个示例中,未选中c因此最终将None添加到整数(这显然不会产生理想的结果)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM