1樓:Pythonyou
第一次執行要傳送None
按照正常流程a=G() 就應該直行到while true可惜不是的,因為只要你這個函式有yield你這個就不是正常的的函式了它的執行方法會變成從外部呼叫,
第一次他執行的時候如果給它發個值, 這個值沒有人接收。
你可能覺得 m = yield i 應該是接收到了, 但是第一次執行send實際根本不是從這執行的!
第一次send 是從 def G() 下面開始執行, 這時候根本沒有變數承接你傳送的值
2樓:靈劍
不能理解為什麼PHP可以,像是個bug……
生成器建立出來的時候還沒有開始執行,next返回第乙個yield的結果,然後send才能向yield表示式傳送資料,固定是生成器先傳送再接收的。但生成器的執行又是完全受控的,所以先需要執行乙個next,是很自然的事情啊。
3樓:
defgen():
fori
inrange(10
):x=yield
iprint(x
)用這個舉例說明:
我把我對這個理解的注釋複製過來,應該非常通俗易懂了
從程式執行流程來看,賦值操作的 = 語句都是從右邊開始執行的
明確這一點,就很好理解了.
來看 x = yield i 這個表示式
如果這個表示式只是x = i,
相信每個人都能理解是把i的值賦值給了x(雖然python是引用,不過不礙事)
而現在等號右邊是乙個yield i,所以先要執行yield i,然後才是賦值
yield把i值返回到了呼叫者那裡
這個表示式的下一步操作:賦值
卻因為等號右邊的yield被暫停了
換句話說x = yield i才執行了一半
當呼叫者通過send(var)回到生成器函式時
是回到之前那個賦值表示式被暫停的那裡
所以接下來執行x = yield i的另一半,那就是這個賦值操作啦
這個值正是呼叫者通過send(var)傳送進生成器的值
然後被列印,然後迴圈下一次執行,然後又來到yield i,然後又暫停,重複以上描述
send(var)之前必須啟動這個生成器,為什麼呢?
因為最開始,gen()函式執行到yield i時,是從gen()把i的值拋回給呼叫者
所以最開始send進去乙個具體值,是幾個意思?順序不對啊!!
現在人家並不是回到gen()生成器,而是第一次執行gen()函式時人家要從gen()那裡出來啊
send(var)是發生在回到gen()時的操作,而不是從gen()出來時的操作,這是需要明確差別的一點
從方便理解的角度上來說
啟動生成器最好還是使用next(),雖然send(None)也可以
因為啟動的時候總是從生成器回到呼叫者的過程
4樓:po wang
今天也發現這個問題,對比了js、python和php,js和python比較像,但js第一次next傳值的話不會有什麼作用,也不會有報錯,php有點不同,php有個current方法,獲取當前值,如果不呼叫current方法,而是直接呼叫send或者next,其實會自動呼叫一次current,但此時send返回的值將是第二個yield後的值了,next不會有返回值
5樓:
這個 python 手冊裡面就有寫吧。python 的 generator 初始化時還沒有被執行。所以你直接用 a = G() 不能達到你想要的效果,要在 a=G() 後面加一句 a.
next() 才開始執行了。開始執行之後才能 send()。
至於為什麼 python 要這樣設計,我覺得是因為歷史原因。
python中的閉包和yield?
Jimmy Cheung 其實嘛,python裡有三種scope,分別是global scope,enclosing scope 和 local scope.第一和第三種就很好理解啦,關鍵在於第二種enclosing scope,closure用的就是這個。當乙個函式wrap另乙個函式 def fo...
Python中yield的輸入錯誤理解在哪?
清都山水郎 推薦閱讀 Fluent Python 的第14章和第16章,該書原作者是巴西的Luciano Ramalho 以及 Effective Python 的第40條,該書原作者是美國的Brett Slatkin。這兩個部分詳細的講述了生成器以及 生成器如何進化成協程 引自安道吳珂所翻譯的Fl...
Python為什麼冒號不對?
qsgdx 樓主的問題應該是中英文標點符號。5個if連用雖然對結果影響不大,但是任何乙個分數程式都會判定5次,這樣的效率很低,建議用if elif else Tobe except print 輸入有誤 else if 100 score int 90 pass二 如果即可以是整數又可以浮點數 sc...