Python关键字yeild

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, 1

             def __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,将事半功倍。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容