2013-10-31 32 views
4

通常當有人發佈他們的代碼時,人們會補充說:「您現在應該使用with open('filename') as f語法。」我同意大多數陳舊的f = open()聲明沒有附帶的.close(),我甚至回答了這樣的問題:對「隱式關閉」的依賴是他們編程問題的全部原因。爲什麼`open()`更適合在Python中打開文件?

但是,在某些情況下,將代碼嵌套到with塊中似乎會在編寫代碼時造成其他不便。例如,我有時候喜歡在開始時使用一個標誌來表示writefile = True。這使我只能打開和關閉文件,如果它將被使用,同時保持相同的處理線程。在代碼中的不同位置,我可以打印到屏幕或寫入文件。 (我知道我會打開stdout或在開始文件,並使用這種方法來代替。)

我的問題是:,除了沒有明確關閉文件,是否有其他原因使用with語法處理文件,特別是輸出文件? (「更多pythonic」本身不是一個理由。)如果這是重複的,我會很高興有這個指出,但我自己找不到它。

+2

不,有with'的'沒有其他好處。如果您的設計從「開放」和「關閉」組合中獲益更多,那麼通過所有方式使用它。 – RickyA

+0

謝謝大家。我很欣賞專業知識和見解。 – beroe

回答

6

There'沒有其他的優勢with:確保清理是唯一的事情。

反正你需要一個範圍的塊,以關閉該文件在出現異常的情況下:

writefile = random.choice([True, False]) 
f = open(filename) if writefile else None 
try: 
    # some code or other 
finally: 
    if writefile: 
     f.close() 

所以,你描述爲with劣勢的東西實在是正確的代碼的缺點(以在需要清理的情況下),無論你如何編寫它。

1

,除了沒有明確關閉文件,是否有其他的原因與語法使用一個文件處理

我覺得對於文件打開時使用ContextManager的主要原因想法,這個文件將在任何情況下都是開放的,無論是否一切正常或者引發異常。

它模擬了以下聲明

f = open(filename, 'w') 
try: 
    pass 
finally: 
    f.close() 
3

我們希望有保證,一些清理/定稿發生。那就是使用with

是的,最常見的,我們想關閉一個文件,但你可以拿出其他的例子。

PEP 343具有非文件例如:

一種用於確保當該塊被留下的鎖,在一個塊的開始獲得的,是 釋放模板:

@contextmanager 
def locked(lock): 
    lock.acquire() 
    try: 
     yield 
    finally: 
     lock.release() 

使用如下:

with locked(myLock): 
    # Code here executes with myLock held. The lock is 
    # guaranteed to be released when the block is left (even 
    # if via return or by an uncaught exception). 
1

例如,我有時候喜歡在開始時使用標誌來表示writefile = True。這使我只能打開和關閉文件,如果它將被使用,同時保持相同的處理線程。在代碼中的不同位置,我可以打印到屏幕或寫入文件。 (我知道我會在開始時打開標準輸出或文件,並使用該方法代替。)

這描述了具有大量重複if語句的代碼。

除了不必顯式地關閉文件外,還有其他的理由使用with語法來處理文件,尤其是輸出文件嗎?

它不再需要編寫自己的finally塊,它的結構你的代碼,這樣你避免重複if語句,它可以讓讀者輕鬆地找到其中一個文件對象(或者更確切地說變量保存文件的地方對象)被定義。

所以不是你們的旗幟的爛攤子,你可以這樣做:

with (open('file') if condition else io.BufferedWriter(sys.stdout)) as f: 
    pass 
相關問題