[英]python3 send() function in generators
根據docs , send() 函數:
“恢復執行並將一個值“發送”到生成器函數中。value 參數成為當前 yield 表達式的結果。send() 方法返回生成器生成的下一個值,或者如果生成器退出而沒有生成,則引發 StopIteration另一個值。當調用 send() 以啟動生成器時,必須以 None 作為參數調用它,因為沒有可以接收該值的 yield 表達式。
但我不明白,為什么在下面的例子中沒有發生“值參數成為當前產量表達式的結果”:
def gen():
yield 1
x = (yield 42)
print(x)
yield 2
>>>c=gen() #create generator
>>>next(c) #prints '1' and stop execution, which is caused by yield 1
>>>c.send(100) #prints '42', because 'The send() method returns the next value yielded by the generator'
>>>next(c) #prints 'None' and '2'
那么為什么 x 變量保持“無”,盡管我通過 c.send(100) 向它發送了 100? 看起來,右側的 yield 表達式分兩步工作:首先它將值返回給生成器的調用者,然后它返回生成器內部發送函數的參數。 如果在 send(42) 之前添加額外的 next(c),我會得到預期的行為,並且程序會打印“100”。 從文檔中我不清楚為什么當我調用 send() 時這兩個步驟不應該同時發生。
那么為什么 x 變量保持“無”,盡管我通過 c.send(100) 向它發送了 100?
因為當前的yield
不是您認為的那樣,而是之前的yield
。
當您發送 100 時,生成器仍然在yield 1
處停止,而不是在yield 42
,因此 100 將是yield 1
的結果,而不是yield 42
。
為了更清楚地看到這一點,如果您修改生成器以檢索z
變量中yield 1
的內容,您將看到z
確實包含 100:
>>> def gen():
... z = yield 1
... x = (yield 42)
... print(x, z)
... yield 2
...
>>> c=gen()
>>> next(c)
1
>>> c.send(100)
42
>>> next(c)
None 100
2
>>>
這就是為什么額外的next()
會打印100
。 回到你的代碼:
def gen():
yield 1 # first next(), stops here (before "getting out" of yield)
x = (yield 42) # second next(), stops here (before "getting out" of yield),
# so, when you send(100), then 100 is given to x and execution goes on, so:
print(x) # 100 is printed
yield 2 # ... and 2.
我想我已經想通了。
c = gen()
您在c
變量中創建了一個生成器,生成器的任何代碼都不會被執行。
next(c)
然后你使用next()
函數, next
函數轉到下一個yield
語句,這里是yield 1
。 所以這個yield
返回1
並停止生成器的執行以嘗試捕獲一個值。
下一行是c.send(100)
,因此yield 1
正在等待一個值並且您提供了它,但是這個值沒有被保存。
send
方法還執行生成器的其余部分,直到下一個yield
語句為:
x = (yield 42)
所以這里的 yield 返回 42 並停止生成器程序以嘗試捕獲一個值。 但在那之后你打電話
next(c)
而且你沒有提供一個值,所以x
現在是 None 。 然后執行剩下的代碼(直到下一個yield
語句,不要忘記)
print(x)
yield 2
所以它打印x
who is None 然后yield
返回 2 並嘗試捕獲一個值。
試試寫這個
c = gen()
next(c)
next(c)
c.send(100)
它會起作用(理解為什么!)
來自文檔: value 參數成為當前 yield 表達式的結果。 send() 方法返回生成器產生的下一個值。
假設我們有以下無限生成器:
def infgen():
a = 0
while True:
a = yield a
a += 1
generato = infgen()
generato.send(None)
輸出:0
.send(None) 的執行與 next() 幾乎相同
現在我們有了 a = 0 的第一個值
代碼停在這里a = yield a
當value 成為當前 yield 表達式的結果時
yielded 表達式是yield a 。 產生expresion的結果是
generato.send(5)
.send(5) 我們將 5 發送到一個in 生成器並繼續:
yielded 表達式的結果是a = 5
一 = 5
+= 1
使用 a = 5 + 1 = 6 轉到 while 循環
並停止並產生 a ,其中 a 為 6
輸出:6
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.