python中,含有yield關鍵字的對象就是一個生成器,每次調用next
方法時會執行到yield
後面的語句,而後返回yield
後面代碼塊的執行結果。其實也能夠調用send方法
下面給個例子方便理解。html
def foo(): bar_a = yield 1 # bar_a是語句塊(yield 1)的返回值,默認爲None bar_b = yield bar_a yield "最後一個值,再迭代就要報StopIteration了" f = foo() # 建立生成器,此時沒有執行foo()裏的任何語句 print(next(f)) # 從foo()裏進入,一直執行到(yield 1)處,此時變量bar_a尚未建立 print(next(f)) # 先將語句塊(yield 1)的返回值賦值個bar_a,此時bar_a的值是None。 # 而後執行到語句塊(yield bar_a),bar_b也尚未被建立 print(next(f)
輸出:python
>>>1 >>>None >>>最後一個值,再迭代就要報StopIteration了
能夠看出,f = foo()
建立生成器時,每次執行到yield
時,會跳出去並將yield
關鍵字後面的內容返回給調用者。下一次有別的調用者再次調用生成器時,會先恢復生成器上次的機器狀態,再接着執行指導遇到yield
或者元素迭代完畢。
並且咱們能夠看到bar_a
和bar_b
是語句yield 1
和yield bar_a
的返回值,注意:不是生成器的返回值。
這裏有個比較繞的地方,咱們用bar_a = yield 1
作分析:express
yield
後面的代碼塊bar_a是語句yield 1
的返回值,這就比如咱們寫函數
a = print('my lover') print('a的值是:', a)
會輸出:翻譯
>>>my lover >>>a的值是: None
def foo(): bar_a = yield 1 bar_b = yield bar_a yield "最後一個值,再迭代就要報StopIteration了" f = foo() print(f.send(None)) print(f.send("my lover")) print(next(f))
輸出:code
>>>1 >>>my lover >>>最後一個值,再迭代就要報StopIteration了
這裏f.send(None)
是初始化生成器,和next(f)
的效果如出一轍。可是不推薦這麼寫,由於不規範。
注意輸出的第二行是字符串my lover,而不是None。這是由於send
函數帶有一個參數,這個參數會覆蓋yield 1
語句的返回值,也就是bar_a的值如今不是None了。htm
官網提到,當咱們建立一個生成器時,第一次調用只能用next()
或者send(None)
。由於此時send傳入其餘參數也沒有yield語句去接收。
這句話我看不懂,說的好像傳入None就有yield來接收似的。各位若是明白的歡迎指點。
原文和傳送門以下:對象
官網傳送門字符串
Resumes the execution and 「sends」 a value into the generator function. The value argument becomes the result of the current yield expression. The send() method returns the next value yielded by the generator, or raises StopIteration if the generator exits without yielding another value. When send() is called to start the generator, it must be called with None as the argument, because there is no yield expression that could receive the value.
Google翻譯版本:
恢復執行並將值「發送」到生成器函數中。所述 值參數成爲當前產量表達的結果。該 send()方法返回由生成器產生的下一個值,或者StopIteration若是生成器退出而不產生另外一個值則引起。當send()調用啓動生成器時,必須將其None做爲參數調用,由於沒有能夠接收該值的yield表達式。
更新:
2018-11-24
對生成器使用send(None)
方法,解釋器在底層會調用__next__
方法,也就是next()
方法get