Python也有关键字,和其他语言一样。大部分语言的关键字的意思是相差不多的,Python的关键字也很丰富,即和其他语言有共性,也有它自身的个性。下面我们就来看看最难懂的关键字yeild。
- yield关键字是Python的一个难点,不是很好理解。首先yeild是一个generator(生成器)。
- yield是一个类似return的关键字,只不过,带有yield的函数,不再是一个普通的函数,而是一个生成器。在执行中,调用next()方法才开始真正执行(for循环自动调用next方法)。
- yeild的作用就是把一个函数变成generator,带有yeild的函数不再是一个普通的函数,Python解释器会将其视为一个generator。
- 带有yeild的函数虽然在执行流程上看起来和普通函数一样,但实际上每执行到yeild的语句,函数就中断,停止执行,每次中断都会通过yeild返回一个当前的迭代值。下次执行的时候从yeild的下一句开始执行,而函数的本地变量看起来和上一次中断执行前是完全一致的,于是函数继续往下执行,直到再次遇到yeild。
以下举例说明上述情况(以Fibonacci数列为例):
-
例一:最简单的斐波纳挈数列:
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
- 例一能实现功能,但是有两个问题,首先这个函数返回None,函数fab()的复用性差,其次这个函数会随着max的增大而逐渐的占用逐渐增大,如果要控制内存的话,这是一个很大的风险点。下面我们改动一下上面的问题: -
例二:把内存控制在一个常数的斐波纳挈数列:
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()不断的返回数列的下一个数,内存占用始终为一个常数: >>>fab(5) 1 1 2 3 5 - 例二虽然内存占用始终为常量,而且同时获得了iterable的效果,但是很复杂,显得很臃肿,远没有例一简洁。这个时候就用到了**yeild**。
-
例三:yeild实现斐波纳挈数列:
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的作用就是把一个函数变成generator,带有yeild的函数不再是一个普通的函数,Python解释器会将其视为一个generator。
2、带有yeild的函数虽然在执行流程上看起来和普通函数一样,但实际上每执行到yeild的语句,函数就中断,停止执行,每次中断都会通过yeild返回一个当前的迭代值。下次执行的时候从yeild的下一句开始执行,而函数的本地变量看起来和上一次中断执行前是完全一致的,于是函数继续往下执行,直到再次遇到yeild。
3、yeild的一个显而易见的好处是把一个函数改写为generator,就获得了迭代功能,就可以用next()计算下一个值。 -
yeild还可以用于大文件的读取,直接调用read()读取,会导致不可预测的内存占用,好的一个方法就是用固定的缓冲区不断的去读取。
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的一个精华关键字,理解了yeild,将事半功倍。
网友评论