[英]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.