Python也有關(guān)鍵字,和其他語言一樣。大部分語言的關(guān)鍵字的意思是相差不多的,Python的關(guān)鍵字也很豐富,即和其他語言有共性,也有它自身的個性。下面我們就來看看最難懂的關(guān)鍵字yeild。
- yield關(guān)鍵字是Python的一個難點,不是很好理解。首先yeild是一個generator(生成器)。
- yield是一個類似return的關(guān)鍵字,只不過,帶有yield的函數(shù),不再是一個普通的函數(shù),而是一個生成器。在執(zhí)行中,調(diào)用next()方法才開始真正執(zhí)行(for循環(huán)自動調(diào)用next方法)。
- yeild的作用就是把一個函數(shù)變成generator,帶有yeild的函數(shù)不再是一個普通的函數(shù),Python解釋器會將其視為一個generator。
- 帶有yeild的函數(shù)雖然在執(zhí)行流程上看起來和普通函數(shù)一樣,但實際上每執(zhí)行到y(tǒng)eild的語句,函數(shù)就中斷,停止執(zhí)行,每次中斷都會通過yeild返回一個當(dāng)前的迭代值。下次執(zhí)行的時候從yeild的下一句開始執(zhí)行,而函數(shù)的本地變量看起來和上一次中斷執(zhí)行前是完全一致的,于是函數(shù)繼續(xù)往下執(zhí)行,直到再次遇到yeild。
以下舉例說明上述情況(以Fibonacci數(shù)列為例):
例一:最簡單的斐波納挈數(shù)列:
def fab(max):
n, a, b = 0, 0, 1
while n < max:
print b
a, b = b, a+b
n += 1
>>>fab(5)
1
1
2
3
5
- 例一能實現(xiàn)功能,但是有兩個問題,首先這個函數(shù)返回None,函數(shù)fab()的復(fù)用性差,其次這個函數(shù)會隨著max的增大而逐漸的占用逐漸增大,如果要控制內(nèi)存的話,這是一個很大的風(fēng)險點。下面我們改動一下上面的問題:-
例二:把內(nèi)存控制在一個常數(shù)的斐波納挈數(shù)列:
class Fab(object):
"""domaxring for Fab"""
def init(self, max):
self.max = max
self.n, self.a, self.b = 0, 0, 1def __iter__(self): return self def next(self): if self.n < self.max: r = self.b self.a, self.b = self.b, self.a+self.b self.n = self.n + 1 return r raise StopIteration() Fab類通過next()不斷的返回數(shù)列的下一個數(shù),內(nèi)存占用始終為一個常數(shù): >>>fab(5) 1 1 2 3 5 - 例二雖然內(nèi)存占用始終為常量,而且同時獲得了iterable的效果,但是很復(fù)雜,顯得很臃腫,遠(yuǎn)沒有例一簡潔。這個時候就用到了**yeild**。 例三:yeild實現(xiàn)斐波納挈數(shù)列:
def fab(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a+b
n = n + 1
>>>for n in fab(5):
print n
1
1
2
3
5
- 這個例子說明:
1、yeild的作用就是把一個函數(shù)變成generator,帶有yeild的函數(shù)不再是一個普通的函數(shù),Python解釋器會將其視為一個generator。
2、帶有yeild的函數(shù)雖然在執(zhí)行流程上看起來和普通函數(shù)一樣,但實際上每執(zhí)行到y(tǒng)eild的語句,函數(shù)就中斷,停止執(zhí)行,每次中斷都會通過yeild返回一個當(dāng)前的迭代值。下次執(zhí)行的時候從yeild的下一句開始執(zhí)行,而函數(shù)的本地變量看起來和上一次中斷執(zhí)行前是完全一致的,于是函數(shù)繼續(xù)往下執(zhí)行,直到再次遇到yeild。
3、yeild的一個顯而易見的好處是把一個函數(shù)改寫為generator,就獲得了迭代功能,就可以用next()計算下一個值。yeild還可以用于大文件的讀取,直接調(diào)用read()讀取,會導(dǎo)致不可預(yù)測的內(nèi)存占用,好的一個方法就是用固定的緩沖區(qū)不斷的去讀取。
def readFile(fpath):
BLOCK_SIZE = 1024
with open(fpath,'rb') as f:
while True:
block = f.read(BLOCK_SIZE)
if block:
yield block
else:
return
yeild是Python的一個精華關(guān)鍵字,理解了yeild,將事半功倍。