2010-07-09 22 views
39

我正在使用CSV模塊讀取製表符分隔的文件。下面的代碼:Python:沒有csv.close()?

z = csv.reader(open('/home/rv/ncbi-blast-2.2.23+/db/output.blast'), delimiter='\t') 

但是當我添加Z.close()來結束我的劇本,我得到和錯誤消息:「csv.reader」對象有沒有屬性‘關閉’」

z.close() 

所以我如何關閉「Z」?

回答

40

讀者實際上只是一個解析器。當您詢問一行數據時,它會將閱讀操作委託給底層的file對象,並將結果轉換爲一組字段。所以沒有必要關閉讀者;這將是一個毫無意義的操作。

但是,您應該確保關閉底層的file對象。在Python 2.5+,這裏是做到這一點的方式:

with open('/home/rv/ncbi-blast-2.2.23+/db/output.blast') as f: 
    z = csv.reader(f, delimiter='\t') 

如果你不熟悉的with statement,它基本上封閉的try...finally塊封閉在finally部分文件內容。對於Python 2.5,您需要導入__future__以啓用with語句。如果您需要保持與早期版本的Python(如2.4)的兼容性,則應該使用try...finally來完成自己的關閉。


感謝Jared爲與with聲明指出兼容性問題。

27

您不直接關閉CSV閱讀器;相反,您應該關閉任何類似文件的對象正在使用。例如,你的情況,你會說:

f = open('/home/rv/ncbi-blast-2.2.23+/db/output.blast') 
z = csv.reader(f, delimiter='\t') 
... 
f.close() 

如果您使用的是最新版本的Python,您可以用語句,例如使用

with open('/home/rv/ncbi-blast-2.2.23+/db/output.blast') as f: 
    z = csv.reader(f, delimiter='\t') 
    ... 

這樣做的優點是f會即使你拋出一個異常,或以其他方式返回與塊,而這樣的情況下,內部會導致剩餘打開前面例子中的文件被關閉。換句話說,它基本上等同於try/finally塊,例如,

f = open('/home/rv/ncbi-blast-2.2.23+/db/output.blast') 
try: 
    z = csv.reader(f, delimiter='\t') 
    ... 
finally: 
    f.close() 
3

您不關閉reader()方法的結果,您關閉open()方法的結果。所以,使用兩條語句:foo=open(...); bar=csv.reader(foo)。然後你可以撥打foo.close()

沒有獎勵積分獎勵在一行中可以更容易閱讀和功能在兩個。