圍觀大神的文件讀取操做

小白版

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

相關文章
相關標籤/搜索