2011-01-05 137 views
18

我認爲這個問題更多的是「編碼風格」而不是技術問題。python關閉文件描述符問題

說我有一行代碼:

buf = open('test.txt','r').readlines() 
... 

將文件描述符自動關閉,還是會留在記憶? 如果文件描述符未關閉,那麼關閉它的更喜歡的方式是什麼?

回答

35

如果您指定的文件對象的變量,你可以明確地使用.close()

f = open('test.txt','r') 
buf = f.readlines() 
f.close() 

或者關閉它(和更普遍首選),你可以使用with關鍵字作爲在Python docs提到(Python的2.5或更大):​​

它是使用with好的做法關鍵字處理文件 對象。這具有以下優點: 該文件在其 套件結束後正確關閉,即使在途中引發異常 。它也比寫等同 的try-finally塊短得多 :

>>> with open('test.txt','r') as f: 
...  buf = f.readlines() 
>>> f.closed 
True 
+1

在這種情況下,「buf」將是一個列表 - 無「關閉」方法。 – jsbueno 2011-01-05 01:23:09

+3

'with'在2.5中可用,但您需要使用'from __future__ import with_statement'導入它。從2.6開始這是不必要的。 – 2011-01-05 01:27:08

+0

@jsbueno感謝您抓住我的錯誤!我更新了答案以反映你的觀察結果! @Jay Conrod,謝謝你的信息! (我從2.4跳到2.7,所以我從來沒有經歷過!) – sahhhm 2011-01-05 01:29:56

5

它會留在內存中,直到垃圾收集器關閉它。您應該始終明確關閉文件描述符。剛做這樣的事情:

with open('test.txt', 'r') as f: 
    buf = f.readlines() 
+5

嚴格來說,使用並不是「明確」關閉文件... – 2011-01-05 01:22:31

+0

@Hugh Bothwell:嗯。我想這取決於你明確的定義。我會打電話給它明確關閉它。 – Falmarri 2011-01-05 05:17:56

+1

只要我們現在知道文件什麼時候會關閉,它就會更加明確,但這並不是我在編程意義上明確要求的。 – 2011-01-05 20:27:16

13

通常在CPython的,該文件被關閉時,引用計數下降到零(儘管這種行爲是不能保證未來的時候了CPython的版本)

在其他實現中,例如Jython,該文件在被garbarge收集之前不會被關閉,這可能會很長時間。

根據實現的行爲,具有不同工作方式的代碼風格很差。

如果它只是一個匆匆的腳本或東西你想在命令解釋器已足夠好了,但對於任何形式的生產工作,你通常應該使用一個上下文管理器在Falmarri的答案

+0

+1好的實踐點。 – martineau 2011-01-05 02:11:15

+1

在不同的Python實現中編碼器的一個例子是Mercurial會在PyPy上運行時耗盡操作系統允許的打開文件的數量。 Mercurial正在進行修改以解決此問題。 – TryPyPy 2011-01-05 02:33:04

1

它會自動關閉了,但是這取決於實施時間。明確使用with-block會更好,但如果你只是爲自己寫一個你偶爾運行的小腳本,那並不重要。

+0

腳本的大小和運行頻率是非常不相關的。如果腳本迭代打開它們的許多文件,如果它沒有關閉它,它確實很重要。遲早它會用完手柄和崩潰。 – 2011-01-05 07:54:24

+1

你是對的,我錯過了寫出重要的部分:那是爲了自己和偶爾。因爲那時,當他用完文件句柄時,他會注意到。 ;)但是如果他把這個放在客戶現場。 : - / – 2011-01-05 07:58:27