2015-03-03 55 views
3

我正在創建我想要接受壓縮文件的軟件。由於文件是在任何地方讀取/寫入的,我創建了一個用於打開文件的實用程序函數,用於處理某些壓縮文件類型的打開/關閉。用open打開的返回文件句柄?

示例代碼:

def return_file_handle(input_file, open_mode="r"): 
    """ Handles compressed and uncompressed files. Accepts open modes r/w/w+ """ 

    if input_file.endswith(".gz") 
     with gzip.open(input_file, open_mode) as gzipped_file_handle: 
      return gzipped_file_handle 

的問題是,使用此代碼時,文件句柄,似乎當關閉功能的回報。我可以做我想要的東西with open還是我需要處理關閉自己?

一下添加到上面的代碼來獲得一個最小的非工作例如:

for line in return_file_handle(input_bed, "rb"): 
    print line 

創建一個gzip壓縮的文本文件:

echo "hei\nder!" | gzip - > test.gz 

錯誤消息:

Traceback (most recent call last): 
    File "check_bed_against_blacklist.py", line 26, in <module> 
    check_bed_against_blacklist("test.gz", "bla") 
    File "check_bed_against_blacklist.py", line 15, in check_bed_against_blacklist 
    for line in return_file_handle(input_bed, "r"): 
ValueError: I/O operation on closed file. 

回答

8

嘗試它作爲發電機:

def return_file_handle(input_file, open_mode="r"): 
""" Handles compressed and uncompressed files. Accepts open modes r/w/w+ """ 

    if input_file.endswith(".gz") 
     with gzip.open(input_file, open_mode) as gzipped_file_handle: 
      yield gzipped_file_handle 

當你把它叫做:

for line in return_file_handle("file.gz"): 
    print line.read() 
+0

這很酷。我沒有意識到python中有多簡單的發生器。我喜歡這個答案是最好的,因爲它會在你讀完之後關閉文件。 – Alejandro 2015-03-03 06:35:58

+0

輝煌,謝謝。謝謝其他人,我贊成你。 – 2015-03-03 08:04:42

2

的風格,你正在使用,以打開該文件,在該塊結束時自動關閉它。這就是打開文件的with塊樣式的全部要點。

你想要做的是:

gzipped_file_handle = gzip.open(input_file, open_mode) 
return gzipped_file_handle 

注意:你只是要小心記住你調用該函數後,關閉該文件。

4

我能想到的最好的辦法是通過一個函數作爲參數,接受FD打開:

def work(fd): 
    for line in fd: 
     print line 

def work_with_file_handle(input_file, func, open_mode="r"): 
    if input_file.endswith(".gz") 
     with gzip.open(input_file, open_mode) as gzipped_file_handle: 
      func(gzipped_file_handle) 

work_with_file_handle('xxx.gz', work) 
+0

非常好,但接受的答案甚至更好。 – 2015-03-03 08:05:33

2

避免,如果你想要回file_handle。因爲當block完成執行時,file_handle會自動關閉。

下面的代碼是你應該用什麼:

import gzip 
def return_file_handle(input_file, open_mode="rb"): 
    if input_file.endswith(".gz"): 
     gzipped_file_handle = gzip.open(input_file, open_mode) 
     return gzipped_file_handle 

for line in return_file_handle('file.txt.gz', "r"): 
    print line