在沒看到大神文件處理操做的時候,我處理文件操做的代碼風格都是以下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