先看乙個簡單的yield語句:
deffib(max):
n, a, b = 0, 0, 1
while n yield
b a, b = b, a +b
n = n + 1
這是有關斐波那契數列的乙個函式,當時正是這個函式中的yield使我困惑導致整個函式不能理解。這個函式包含yield,實際上這已經是乙個生成器(generator)了,這與普通的函式有很大的不同。
defh():
'hello
'yield 6h()
可以看到,呼叫h()之後,print 語句並沒有執行!這就是yield,那麼,如何讓print 語句執行呢?這就是後面要討論的問題,通過後面的討論和學習,就會明白yield的工作原理了。
2. yield是乙個表示式
python2.5以前,yield是乙個語句,但現在2.5中,yield是乙個表示式(expression),比如:
x = yield 6
表示式(yield 6)的返回值將賦值給x,所以,認為 x = 5 是錯誤的。那麼如何獲取(yield 5)的返回值呢?需要用到後面要介紹的send(msg)方法。
3. 透過next()語句看原理
現在,我們來揭曉yield的工作原理。我們知道,我們上面的h()被呼叫後並沒有執行,因為它有yield表示式,因此,我們通過next()語句讓它執行。next()語句將恢復generator執行,並直到下乙個yield表示式處。比如:
defh():
print('
hello
')yield 6
print('
python!
')c =h()
c.__next__() #這裡是雙下劃線
c.next()呼叫後,h()開始執行,直到遇到yield 6,因此輸出結果:
hello
hellotraceback (most recent call last):
python!
file
"c:/users/zxj/pycharmprojects/firstproject/day4/test.py
", line 29, in
c.__next__
()stopiteration
4. send(msg) 與 next()
了解了next()如何讓包含yield的函式執行後,我們再來看另外乙個非常重要的函式send(msg)。其實next()和send()在一定意義上作用是相似的,區別是send()可以傳遞yield表示式的值進去,而next()不能傳遞特定的值,只能傳遞none進去。因此,我們可以看做
c.next() 和 c.send(none) 作用是一樣的。
來看這個例子:
defh():
print('hello'),
x = yield 6
m y = yield 23
'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 。到這裡,是不是明白了一些什麼東西?我們再延續上面的例子:
defh():
print('
hello')
x = yield 6
(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)
輸出結果:
hellook6 23
python中的yield關鍵字的用法詳情
閱讀別人的python原始碼時碰到了這個yield這個關鍵字,各種搜尋終於搞懂了,在此做一下總結 通常的for in 迴圈中,in後面是乙個陣列,這個陣列就是乙個可迭代物件,類似的還有鍊錶,字串,檔案。它可以是mylist 1,2,3 也可以是mylist x x for x in range 3 ...
Python中的yield用法
在python中,我們將帶有 yield 的函式稱之為 generator 生成器 generator可以一邊迴圈一邊計算,是可迭代物件,也就是說可以使用for迴圈來迭代出generator的各個值。一般為了說明generator,都會使用斐波那契數列來舉例,這裡也不例外 如結果所示,呼叫 fab ...
Python中的yield用法
yield關鍵字用來定義生成器 generator 其具體功能是可以當return使用,從函式裡返回乙個值,不同之處是用yield返回之後,可以讓函式從上回yield返回的地點繼續執行。也就是說,yield返回函式,交給呼叫者乙個返回值,然後再 瞬移 回去,讓函式繼續執行,直到嚇一條yield語句再...