[英]Confusing python yield behavior
我今天遇到了一个有趣的yield
行为,我真的不明白。 这是我的代码:
def a():
def b(x):
print("entering b.")
yield 0
if x == 0:
print("calling b.")
b(x + 1)
print("return from b.")
print("leaving b.")
for x in b(0):
yield x
for x in a():
print(x)
那输出:
entering b.
0
calling b.
return from b.
leaving b.
令我困惑的是,显式调用b(x + 1)
不会调用b
(!),Python也不会给出任何错误或异常。
现在,显然上面代码中的错误是b(x + 1)
应该真正产生b
产生的值 - 所以它应该读取如下内容:
for x in b(x + 1):
yield x
事情就好了。
不过,这应该是我应该注意的yield
吗?
调用b(x + 1)
,但直到在调用函数的上下文中产生才执行。
使用yield from
产生该调用b()
产生的所有值并执行body:
def a():
def b(x):
print("entering b.")
yield 0
if x == 0:
print("calling b.")
yield from b(x + 1)
print("return from b.")
print("leaving b.")
for x in b(0):
yield x
for x in a():
print(x)
你到目前为止得到的答案是正确的 (我已经对它进行了投票),但是我看到你还在为此而斗争,所以让我们试试这个变种:
def a():
def b(x):
print("entering b.")
yield 0
if x == 0:
print("calling b.")
temp = b(x + 1)
print("calling b resulted in temp =", temp)
print("return from b.")
print("leaving b.")
for x in b(0):
yield x
for x in a():
print(x)
现在让我们在Python 3.x中运行它:
entering b.
0
calling b.
calling b resulted in temp = <generator object a.<locals>.b at 0x800ac9518>
return from b.
leaving b.
也就是说, temp
被设置为调用b(x + 1)
结果 , 结果就是这个<generator object ...>
东西。
然后,你必须做的发电机对象的东西,所以这里又是第三方案:
def a():
def b(x):
print("entering b.")
yield 0
if x == 0:
print("calling b.")
temp = b(x + 1)
print("calling b resulted in temp =", temp)
y = next(temp)
print("by doing next(temp), I got", y)
print("return from b.")
print("leaving b.")
for x in b(0):
yield x
for x in a():
print(x)
运行它会产生:
entering b.
0
calling b.
calling b resulted in temp = <generator object a.<locals>.b at 0x800ac9518>
entering b.
by doing next(temp), I got 0
return from b.
leaving b.
另一个答案中变体的yield from
基本上意味着“继续调用温度并收益它产生的任何东西,直到它说它完成了”。 这个y = next(temp)
调用一次temp。
为读者练习:尝试下面引用的第四个变体。 在运行它之前,尝试预测一下你会看到的内容。 你看到你的预测吗?
def a():
def b(x):
print("entering b.")
yield 0
if x == 0:
print("calling b.")
temp = b(x + 1)
print("calling b resulted in temp =", temp)
y = next(temp)
print("by doing next(temp), I got", y)
try:
print("about to re-enter temp")
y = next(temp)
print("with the second next(temp), I got", y)
except StopIteration:
print("with the second next(temp), I got StopIteration")
print("return from b.")
else:
print("b had x =", x)
print("leaving b.")
for x in b(0):
yield x
for x in a():
print(x)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.