Python yield 使用浅析-生成器

# 通过`yield`来创建生成器
def func():
   for i in range(10):
       yield i

>>> f # 此时生成器还没有运行
<generator object func at 0x7fe01a853820>
>>> f.__next__() # 当i=0时,遇到yield关键字,直接返回
0
>>> f.__next__() # 继续上一次执行的位置,进入下一层循环
1
---------------------------------------------------
# 通过列表来创建生成器
[i for i in range(10)]
#除了next函数,生成器还支持send函数。该函数可以向生成器传递参数。

Python yield 使用浅析

'''清单 1. 简单输出斐波那契數列前 N 个数'''
def fab(max):
   n, a, b = 0, 0, 1
   while n < max:
       print (b)
       a, b = b, a + b
       n = n + 1
fab(10)

'''
有经验的开发者会指出,直接在 fab 函数中用 print 打印数字会导致该函数可复用性较差,因为 fab 函数返回 None,其他函数无法获得该函数生成的数列。
要提高 fab 函数的可复用性,最好不要直接打印出数列,而是返回一个 List。以下是 fab 函数改写后的第二个版本:
清单 2. 输出斐波那契數列前 N 个数第二版'''
def fab1(max):
   n, a, b = 0, 0, 1
   L = []
   while n < max:
       L.append(b)
       a, b = b, a + b
       n = n + 1
   print(L)
   return L
fab1(10)

print('*'*20)

'''
 class 改写的这个版本,代码远远没有第一版的 fab 函数来得简洁。如果我们想要保持第一版 fab 函数的简洁性,同时又要获得 iterable 的效果,yield 就派上用场了:
清单 5. 使用 yield 的第四版'''
def fab4(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        # print b
        a, b = b, a + b
        n = n + 1
print(fab4(10)) #同一地址
for n in fab4(5):
    print(n)
print(fab4(5))

fab 和 fab(5),fab 是一个 generator function,而 fab(5) 是调用 fab 返回的一个 generator,好比类的定义和类的实例的区别。

2、另一个 yield 的例子来源于文件读取。如果直接对文件对象调用 read() 方法,会导致不可预测的内存占用。好的方法是利用固定长度的缓冲区来不断读取文件内容。通过 yield,我们不再需要编写读文件的迭代类,就可以轻松实现文件读取:

def read_file(fpath): 
   BLOCK_SIZE = 1024 
   with open(fpath, 'rb') as f: 
       while True: 
           block = f.read(BLOCK_SIZE) 
           if block: 
               yield block 
           else: 
               return

猜你喜欢

转载自blog.csdn.net/sinat_23880167/article/details/82851685
今日推荐