python 台发电机的精确 return 产量点
Exact return point of yield in python generators
为了自学 Python 生成器,尤其是他们的 send()
方法,我想编写一个玩具示例来计算 "interruptible" 斐波那契数列。
最后我成功了,但我不明白到底是怎么回事。考虑这两个例子。
成功范例:
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'
为什么第二个示例不起作用? 特别是,第二个示例似乎在所有 [=36] 中将 None
的值分配给 c
=]但是生成器的第一个次执行。为什么?它如何知道在第一次调用 next()
时分配给 c
,而不是下一次 next()
时间?
我的理解是生成器恢复执行(当它们被再次调用时)从 yield 线 之后 行开始,但我的例子让我认为这是错误的,至少在某些情况下。执行从哪里恢复?它是否重新执行 yield
行,但这次以某种方式在 yield
之后删除了所有内容? c
如何分配给 None
?
yield
有点奇怪。在计算右侧之后但在赋值发生之前,执行在 yield
处暂停。
yield
语句中返回的值是您 .send
生成器的任何值。由于您调用的是 .next
而不是 .send
,因此从 yield 表达式 (c
) 返回的值是 None
。在第一个示例中,这很好,因为检查了 c
的真实性,如果它是假的则不使用(例如 None
)。但是,在第二个示例中,未检查 c
,因此您最终将 None
添加到一个整数(这显然不会产生理想的结果)。
为了自学 Python 生成器,尤其是他们的 send()
方法,我想编写一个玩具示例来计算 "interruptible" 斐波那契数列。
最后我成功了,但我不明白到底是怎么回事。考虑这两个例子。
成功范例:
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'
为什么第二个示例不起作用? 特别是,第二个示例似乎在所有 [=36] 中将 None
的值分配给 c
=]但是生成器的第一个次执行。为什么?它如何知道在第一次调用 next()
时分配给 c
,而不是下一次 next()
时间?
我的理解是生成器恢复执行(当它们被再次调用时)从 yield 线 之后 行开始,但我的例子让我认为这是错误的,至少在某些情况下。执行从哪里恢复?它是否重新执行 yield
行,但这次以某种方式在 yield
之后删除了所有内容? c
如何分配给 None
?
yield
有点奇怪。在计算右侧之后但在赋值发生之前,执行在 yield
处暂停。
yield
语句中返回的值是您 .send
生成器的任何值。由于您调用的是 .next
而不是 .send
,因此从 yield 表达式 (c
) 返回的值是 None
。在第一个示例中,这很好,因为检查了 c
的真实性,如果它是假的则不使用(例如 None
)。但是,在第二个示例中,未检查 c
,因此您最终将 None
添加到一个整数(这显然不会产生理想的结果)。