2010-01-02 100 views
4

事實證明,「with」是一個在互聯網上搜索的有趣單詞。在Python中嵌套'WITH'語句

有誰知道在Python中嵌套語句是怎麼處理的?
我一直在跟蹤腳本中的我已經寫了一個很滑的錯誤,我懷疑這是因爲我在做這樣的:當我嘗試從read() fsock2

with open(file1) as fsock1: 
    with open(file2, 'a') as fsock2: 
     fstring1 = fsock1.read() 
     fstring2 = fsock2.read() 

Python中拋出了。在調試器中檢查後,這是因爲它認爲文件是空的。這不會令人擔憂,除非在調試interperter中運行完全相同的代碼而不是在with聲明中顯示該文件實際上充滿了文本...

我要去繼續假設現在嵌套with陳述是一個禁忌,但如果誰知道更多有不同的意見,我很樂意聽到它。

回答

4

我在python的doc中找到了解決方案。你可能想看看this

如果你正在運行的Python 3.1+,你可以使用它像這樣:

with open(file1) as fsock1, open(file2, 'a') as fsock2: 
    fstring1 = fsock1.read() 
    fstring2 = fsock2.read() 

這樣你避免不必要的縮進。

6

AFAIK您無法讀取以追加模式打開的文件'a'

+0

我只是想實現同樣的事情時對自己的問題發表評論。我覺得......現在很愚蠢。 – Geoff 2010-01-02 02:28:32

1

嵌套with陳述沒有問題 - 相反,您打開file2追加,因此您無法讀取它。

如果您不喜歡嵌套with語句,無論出於何種原因,您通常可以避免使用contextlib.nested函數。但是,它不會破壞代碼(例如,打開文件以進行追加,然後嘗試讀取文件的代碼),也不會在詞彙上嵌套with語句來破壞本來不錯的代碼。

3

在調試器中檢查時,這是因爲它認爲文件是空的。

我認爲這是因爲它實際上不能讀取任何東西。即使它可以,當你附加到一個文件時,seek指針會被移動到文件的末尾,以便寫入發生。

這些with聲明只是正常工作對我來說:

with open(file1) as f: 
    with open(file2, 'r') as g: # Read, not append. 
     fstring1 = f.read() 
     fstring2 = g.read() 

注意,使用的contextlib.nested,作爲另一個海報建議,與這裏的危險可能誤人子弟。假設你這樣做:

with contextlib.nested(open(file1, "wt"), open(file2)) as (f_out, f_in): 
    ... 

這裏的上下文管理器一次創建一個。這意味着如果file2的打開失敗(比如說因爲它不存在),那麼你將無法正確地完成file1,並且必須將其留給垃圾收集器。這可能是一件非常糟糕的事情。

0

至於搜索「with」,用'+'前綴一個單詞可以防止谷歌忽略它。

+0

有用!謝謝。 – Geoff 2010-01-03 20:14:29

+1

這曾經是事實。現在你必須用引號把它括起來,例如''帶着''。 – 2014-04-03 11:11:33