什么是yield?
一句話理解:讓普通函數(shù),變成一個生成器(generator)[一個特殊的函數(shù)],函數(shù)里碰到y(tǒng)ield就返回一次值。
yield 關(guān)鍵字就可以理解成和return一樣功能,返回一個值。
生成器,生成器,就是使用了next才會生成一段yield的值。就是next指揮它跑一段,碰到y(tǒng)ield就停下來,下次再從上次停的地方開始跑。
一個例子:
def foo():
print("starting...")
while True:
res = yield 4
print("res:",res)
g = foo()
print(next(g))
print("*"*20)
print(next(g))
代碼輸出:
starting... 4 ******************** res: None 4
我直接解釋代碼運行順序,相當(dāng)于代碼單步調(diào)試:
1.程序開始執(zhí)行以后,因為foo函數(shù)中有yield關(guān)鍵字,所以foo函數(shù)并不會真的執(zhí)行,而是先得到一個生成器g(相當(dāng)于一個對象)
2.直到調(diào)用next方法,foo函數(shù)正式開始執(zhí)行,先執(zhí)行foo函數(shù)中的print方法,然后進(jìn)入while循環(huán)
3.程序遇到y(tǒng)ield關(guān)鍵字,然后把yield想想成return,return了一個4之后,程序停止,并沒有執(zhí)行賦值給res操作,此時next(g)語句執(zhí)行完成,所以輸出的前兩行(第一個是while上面的print的結(jié)果,第二個是return出的結(jié)果)是執(zhí)行print(next(g))的結(jié)果,
4.程序執(zhí)行print("*"*20),輸出20個*
5.又開始執(zhí)行下面的print(next(g)),這個時候和上面那個差不多,不過不同的是,這個時候是從剛才那個next程序停止的地方開始執(zhí)行的,也就是要執(zhí)行res的賦值操作,這時候要注意,這個時候賦值操作的右邊是沒有值的(因為剛才那個是return出去了,并沒有給賦值操作的左邊傳參數(shù)),所以這個時候res賦值是None,所以接著下面的輸出就是res:None,
6.程序會繼續(xù)在while里執(zhí)行,又一次碰到y(tǒng)ield,這個時候同樣return 出4,然后程序停止,print函數(shù)輸出的4就是這次return出的4.
總結(jié):也就是有yield的函數(shù),是生成器,生成器在調(diào)用的時候并不會真正執(zhí)行【g = foo() 這樣是不會真正執(zhí)行】
只有調(diào)用了next(g),才會真正執(zhí)行到碰到有yield的地方,然后就返回yield的值(比如yield 4)。
下一次再調(diào)用next(g)時,從剛剛yield返回的后面開始執(zhí)行。直到下一次碰到next()
----------------------------------------------------
另一個例子:斐波那契(Fibonacci)數(shù)列是一個非常簡單的遞歸數(shù)列,除第一個和第二個數(shù)外,任意一個數(shù)都可由前兩個數(shù)相加得到。
計算斐波那契(Fibonacci)數(shù)列。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
def fab(max):
n, a, b = 0, 0, 1
while n < max:
yield b # 使用 yield
# print b
a, b = b, a + b
n = n + 1
for n in fab(5):
print n
在 for 循環(huán)中會自動調(diào)用 next()。
當(dāng)函數(shù)執(zhí)行結(jié)束時,generator 自動拋出 StopIteration 異常,表示迭代完成。在 for 循環(huán)里,無需處理 StopIteration 異常,循環(huán)會正常結(jié)束。
也可以手動調(diào)用next()
>>>f = fab(5) >>> f.next() 1 >>> f.next() 1 >>> f.next() 2 >>> f.next() 3 >>> f.next() 5 >>> f.next() Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
總結(jié)
- 上一篇: 【笔记】3D相机与测量原理
- 下一篇: 一个简单的Linux后门程序的实现