Python也有關(guān)鍵字躲舌,和其他語(yǔ)言一樣会通。大部分語(yǔ)言的關(guān)鍵字的意思是相差不多的口予,Python的關(guān)鍵字也很豐富,即和其他語(yǔ)言有共性涕侈,也有它自身的個(gè)性沪停。下面我們就來(lái)看看最難懂的關(guān)鍵字yeild。
- yield關(guān)鍵字是Python的一個(gè)難點(diǎn)裳涛,不是很好理解木张。首先yeild是一個(gè)generator(生成器)。
- yield是一個(gè)類似return的關(guān)鍵字端三,只不過(guò)舷礼,帶有yield的函數(shù),不再是一個(gè)普通的函數(shù)郊闯,而是一個(gè)生成器妻献。在執(zhí)行中,調(diào)用next()方法才開始真正執(zhí)行(for循環(huán)自動(dòng)調(diào)用next方法)团赁。
- yeild的作用就是把一個(gè)函數(shù)變成generator,帶有yeild的函數(shù)不再是一個(gè)普通的函數(shù)育拨,Python解釋器會(huì)將其視為一個(gè)generator。
- 帶有yeild的函數(shù)雖然在執(zhí)行流程上看起來(lái)和普通函數(shù)一樣然痊,但實(shí)際上每執(zhí)行到y(tǒng)eild的語(yǔ)句,函數(shù)就中斷屉符,停止執(zhí)行剧浸,每次中斷都會(huì)通過(guò)yeild返回一個(gè)當(dāng)前的迭代值锹引。下次執(zhí)行的時(shí)候從yeild的下一句開始執(zhí)行,而函數(shù)的本地變量看起來(lái)和上一次中斷執(zhí)行前是完全一致的唆香,于是函數(shù)繼續(xù)往下執(zhí)行嫌变,直到再次遇到yeild。
以下舉例說(shuō)明上述情況(以Fibonacci數(shù)列為例):
例一:最簡(jiǎn)單的斐波納挈數(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
- 例一能實(shí)現(xiàn)功能躬它,但是有兩個(gè)問(wèn)題腾啥,首先這個(gè)函數(shù)返回None,函數(shù)fab()的復(fù)用性差冯吓,其次這個(gè)函數(shù)會(huì)隨著max的增大而逐漸的占用逐漸增大倘待,如果要控制內(nèi)存的話,這是一個(gè)很大的風(fēng)險(xiǎn)點(diǎn)组贺。下面我們改動(dòng)一下上面的問(wèn)題:-
例二:把內(nèi)存控制在一個(gè)常數(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類通過(guò)next()不斷的返回?cái)?shù)列的下一個(gè)數(shù)凸舵,內(nèi)存占用始終為一個(gè)常數(shù): >>>fab(5) 1 1 2 3 5 - 例二雖然內(nèi)存占用始終為常量,而且同時(shí)獲得了iterable的效果失尖,但是很復(fù)雜啊奄,顯得很臃腫,遠(yuǎn)沒(méi)有例一簡(jiǎn)潔掀潮。這個(gè)時(shí)候就用到了**yeild**菇夸。
例三:yeild實(shí)現(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
- 這個(gè)例子說(shuō)明:
1、yeild的作用就是把一個(gè)函數(shù)變成generator,帶有yeild的函數(shù)不再是一個(gè)普通的函數(shù)仪吧,Python解釋器會(huì)將其視為一個(gè)generator庄新。
2、帶有yeild的函數(shù)雖然在執(zhí)行流程上看起來(lái)和普通函數(shù)一樣邑商,但實(shí)際上每執(zhí)行到y(tǒng)eild的語(yǔ)句摄咆,函數(shù)就中斷,停止執(zhí)行人断,每次中斷都會(huì)通過(guò)yeild返回一個(gè)當(dāng)前的迭代值吭从。下次執(zhí)行的時(shí)候從yeild的下一句開始執(zhí)行,而函數(shù)的本地變量看起來(lái)和上一次中斷執(zhí)行前是完全一致的恶迈,于是函數(shù)繼續(xù)往下執(zhí)行涩金,直到再次遇到yeild。
3暇仲、yeild的一個(gè)顯而易見的好處是把一個(gè)函數(shù)改寫為generator步做,就獲得了迭代功能,就可以用next()計(jì)算下一個(gè)值奈附。yeild還可以用于大文件的讀取全度,直接調(diào)用read()讀取,會(huì)導(dǎo)致不可預(yù)測(cè)的內(nèi)存占用斥滤,好的一個(gè)方法就是用固定的緩沖區(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的一個(gè)精華關(guān)鍵字勉盅,理解了yeild,將事半功倍。