python生成器中的精确屈服点

2024-10-01 00:32:23 发布

您现在位置:Python中文网/ 问答频道 /正文

为了自学Python生成器,特别是它们的send()方法,我想编写一个玩具示例,让我能够计算一个“可中断的”Fibonacci序列。你知道吗

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

成功范例:

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'

为什么第二个例子不起作用?特别是,第二个示例似乎在生成器的所有执行中都将值None赋给c,但第一个执行除外。为什么?它如何知道在第一次调用next()时分配给c,而不是下一次next()时分配给c?你知道吗

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


Tags: sendtrue示例numberreturndefipython例子
1条回答
网友
1楼 · 发布于 2024-10-01 00:32:23

yield有点奇怪。在计算右侧之后,但在赋值发生之前,执行在yield处暂停。你知道吗

yield语句中返回的值是您.send给生成器的值。由于调用的是.next,而不是.send,因此从yield表达式(c)返回的值是None。在第一个例子中,这很好,因为c被检查为真实性,如果它是虚假的,则不使用它(例如None)。但是,在第二个示例中,c没有被选中,因此最终将None添加到整数中(这显然不会产生理想的结果)。你知道吗

相关问题 更多 >