圍觀大神的檔案讀取操作
阿新 • • 發佈:2020-07-23
小白版
在沒看到大神檔案處理操作的時候,我處理檔案操作的程式碼風格都是如下
# 讀取小檔案 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倍,記憶體佔用更是不到原來的百分之一