在没看到大神文件处理操做的时候,我处理文件操做的代码风格都是以下python
# 读取小文件 with open('file_path','rb') as f: content = f.read() # TODO 逻辑处理... # 读取大文件 with open('file_path','rb') as f: for line in f: # TODO 逻辑处理... # 处理极端状况,大文件且数据都在一行中 with open('file_path','rb') as f: block_size = 1024*8 while 1: chunk = f.read(block_size) if not chunk: break # TODO 逻辑处理...
利用生成器,解耦读取和生成函数
def file_reader(fp,block_size=1024*8): while 1: chunk = fp.read(block_size) if not chunk: break yield chunk def handle_data(fpath): with open(fpath,'rb') as f: for chunk in file_reader(f) # TODO 逻辑处理...
彷佛看了上面的代码,感受没啥改进的了,其实否则,iter()是一个用来构造迭代器的内建函数,但它还有一个方法,iter(callable,sentinel),会返回一个特殊的对象,迭代它将不断产生callable的调用结果,直到结果为sentinel为止性能
def file_reader(fp,block_size=1024*8): # 利用partial只是方便构造一个不用传入参数的函数而已 # 循环不断返回fp.read的结果,直到结果为''则中止迭代 for chunk in iter(partial(fp.read,block_size),'') yield chunk
上面的读取操做只用了2行解决,那么性能到底如何呢,从一开始的循环读取到生成器,效率提高了近4倍,内存占用更是不到原来的百分之一code