按固定长度读取文件

 1 def read_in_block(file_path):
 2     BLOCK_SIZE = 100
 3     with open(file_path, "rb") as f:
 4         while True:
 5             con = f.read(BLOCK_SIZE)  # 每次读取固定长度到内存缓冲区
 6             yield con
 7             if con == b'':
 8                 break # 如果读取到文件末尾,则退出
 9 
10 fpath = "../file/1024.txt"
11 for block in read_in_block(fpath):
12     print(block)

 

 这里给自己补充2个概念:

可迭代对象(Iterables) 
创建一个列表list时,你可以逐个地读取里面的每一项元素,这个过程称之为迭代(iteration)

list = [1,2,3]
for i in list:
    print(i)

 

 

迭代器(iterator)
  迭代器代表一个数据流对象,不断重复调用迭代器的next()方法逐次的从返回数据流中的每一项,当没有更多数据可用时,next()方法会抛出异常StopIteration。此时迭代器对象已经枯竭了,之后调用next()方法都会抛出StopIteration。迭代器需要一个__iter__()方法用来返回迭代器本身,因此它也是一个可迭代的对象。
生成器(Generators) 
  生成器也是一个迭代器,但是你只可以迭代它们一次,不能重复迭代,因为它并没有把所有的值存储在内存中,而是实时地生成值:

Generators = (2*x for x in range(3))
for i in Generators:
    print(i)

 

 从结果上看用()代替[]的效果是一样的,但是你不可能第二次执行for i in Generators:,因为生成器只能使用一次

Yield 
yield是关键字,它类似于return,只是函数会返回一个生成器。

 

一个带有 yield 的函数就是一个 generator,它和普通函数不同,生成一个 generator 看起来像函数调用,但不会执行任何函数代码,直到对其调用 next()(在 for 循环中会自动调用 next())才开始执行。虽然执行流程仍按函数的流程执行,但每执行到一个 yield 语句就会中断,并返回一个迭代值,下次执行时从 yield 的下一个语句继续执行。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。
yield 的好处是显而易见的,把一个函数改写为一个 generator 就获得了迭代能力,比起用类的实例保存状态来计算下一个 next() 的值,不仅代码简洁,而且执行流程异常清晰。
使用Yield的一个例子,从文件读取内容。 
如果直接对文件 对象调用read()方法,会导致不可预测的内存占用。好的方法是利用固定长度的缓冲区来不断读取文件内容。通过yield,我们不在需要编写读取文件的迭代类,就可以轻松实现文件读取:

 

posted @ 2022-01-20 18:12  wellons  阅读(190)  评论(0编辑  收藏  举报