2010-03-23 100 views
2

pickle module documentation有的示例代碼片段:蟒持續時間

reader = pickle.load(open('save.p', 'rb')) 

,其在第一讀取看起來像是將分配系統文件描述符,讀取其內容,然後「泄漏」開放描述符,因爲沒有可訪問的任何句柄可以調用close()。這讓我想知道是否有任何隱藏的魔法來處理這種情況。

潛入源代碼中,我在Modules/_fileio.c中發現文件描述符被導致真正問題的fileio_dealloc()析構函數關閉。

以上示例代碼使用的文件對象的持續時間是多少?在該語句執行之後,該對象是否確實變爲未被引用,因此fd在將來的垃圾收集掃描時是否會受到實際的close(2)調用?如果是這樣,是示例行的良好做法,還是應該不指望正在發佈的fd,從而冒着內核每進程描述符表耗盡的風險?

回答

3

什麼是文件 對象的持續時間由示例代碼以上 返回?

代碼不回報文件對象(如Q的標題正確地說,它接受它作爲參數)。

在當前的CPython中,函數返回時該文件將被關閉(因爲該函數不會將對文件對象的任何引用存儲到更持久的位置)。在其他實現中,該文件將「最終」關閉,但沒有指定精確的時間。

取決於CPython的即時封閉語義(當未來的CPython轉向更好的垃圾收集機制時可能會發生變化),而傳統方法並不是最佳實踐。

相反,最好的做法是使用with聲明:

with open(...) as f: 
    reader = pickle.load(f) 

隨着這個使用,該文件的立即關閉(只要with語句體結束)在所有的實現保證。

請注意,在Python 2.5中,您需要from __future__ import with_statement才能使用with。在2.6或更高版本中,這樣的「從未來導入」並不是必需的(這是無害的,但如果你知道你永遠不會在2.5以下運行,那麼它是多餘的並且更好地移除)。

+0

非常感謝;你是對的,我的意思是「使用」而不是「返回」並編輯修復。 – msw 2010-03-23 04:20:02