今天看python學習視頻學到生成器這一塊時始終弄不懂yield的用法及其原理,在網上詳細查看yield的用法以後總結一下yield的使用方法。python
先看一個簡單的yield語句:函數
def fib(max): n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + b n = n + 1
這是有關斐波那契數列的一個函數,當時正是這個函數中的yield使我困惑致使整個函數不能理解。這個函數包含yield,實際上這已是一個生成器(generator)了,這與普通的函數有很大的不一樣。學習
def h(): print 'hello' yield 6 h()
能夠看到,調用h()以後,print 語句並無執行!這就是yield,那麼,如何讓print 語句執行呢?這就是後面要討論的問題,經過後面的討論和學習,就會明白yield的工做原理了。spa
2. yield是一個表達式code
Python2.5之前,yield是一個語句,但如今2.5中,yield是一個表達式(Expression),好比:視頻
x = yield 6blog
表達式(yield 6)的返回值將賦值給x,因此,認爲 x = 5 是錯誤的。那麼如何獲取(yield 5)的返回值呢?須要用到後面要介紹的send(msg)方法。generator
3. 透過next()語句看原理io
如今,咱們來揭曉yield的工做原理。咱們知道,咱們上面的h()被調用後並無執行,由於它有yield表達式,所以,咱們經過next()語句讓它執行。next()語句將恢復Generator執行,並直到下一個yield表達式處。好比:ast
def h(): print('hello') yield 6 print('python!') c = h() c.__next__() #這裏是雙下劃線
c.next()調用後,h()開始執行,直到遇到yield 6,所以輸出結果:
hello
當咱們再次調用c.next()時,會繼續執行,直到找到下一個yield表達式。因爲後面沒有yield了,所以會拋出異常:
hello Traceback (most recent call last): python! File "C:/Users/zxj/PycharmProjects/firstProject/day4/test.py", line 29, in <module> c.__next__() StopIteration
4. send(msg) 與 next()
瞭解了next()如何讓包含yield的函數執行後,咱們再來看另一個很是重要的函數send(msg)。其實next()和send()在必定意義上做用是類似的,區別是send()能夠傳遞yield表達式的值進去,而next()不能傳遞特定的值,只能傳遞None進去。所以,咱們能夠看作
c.next() 和 c.send(None) 做用是同樣的。
來看這個例子:
def h(): print('hello'), x = yield 6 print m y = yield 23 print 'python' c = h() c.__next__() #至關於c.send(None) c.send('ok') #(yield 6)表達式被賦予了'ok'
輸出的結果爲:
hello
ok
須要提醒的是,第一次調用時,請使用next()語句或是send(None),不能使用send發送一個非None的值,不然會出錯的,由於沒有yield語句來接收這個值。
5. send(msg) 與 next()的返回值
send(msg) 和 next()是有返回值的,它們的返回值很特殊,返回的是下一個yield表達式的參數。好比yield 6,則返回 6 。到這裏,是否是明白了一些什麼東西?咱們再延續上面的例子:
def h(): print('hello') x = yield 6 print(m) y = yield 23 print (y) c = h() x = c.__next__() #x 獲取了yield 6 的參數值 6 y = c.send('ok') #y 獲取了yield 23 的參數值23 print(x,y)
輸出結果:
hello
ok
6 23
以上就是python中有關yield用法方面的總結,若有不對的地方或者不全面的地方歡迎你們批評指正!!!