2015-02-23 77 views
5

我知道文件進行閱讀開放最好的辦法/寫與withPython的打開和讀取文件中的一個襯墊

使用,而不是使用

f = open('file.txt', 'w') 
f.write('something') 
f.close() 

我們應該寫 -

with open('file.txt', 'w') as f: 
    f.write('something') 

但是如果我想簡單地讀一個文件呢?我能做到這一點

with open('file.txt') as f: 
    print (f.read()) 

但什麼是在下面一行的問題

print (open('file.txt').read())

OR

alist = open('file.txt').readlines() 
print (alist) 

它會自動執行此語句後,關閉該文件?這是一種標準的寫作方式嗎?我們應該這樣寫嗎?

除此之外 - 我應該打開一個函數中的文件,並將指針傳遞給其他寫入,或者我應該宣佈它爲全局變量?即

def writeto(f): 
    #do some stuff 
    f.write('write stuff') 

def main(): 
    f = open('file.txt', 'w') 
    while somecondition: 
     writeto(f) 
    f. close() 

OR

f = open('file.txt', 'w') 

def writeto(): 
    #do some stuff 
    f.write('write stuff') 

def main(): 
    while somecondition: 
     writeto() 

f. close() 
+0

順便說一句,在直截了當的答案在標題中提出的問題是這樣的:'開放(「file.txt的」,「W」)爲f:F .write('some text')'用於寫入或用'open('file.txt')作爲f:contents = f.read()'來讀取。 – 2015-02-23 19:26:06

回答

3

解決您的才能問題,

「這有什麼錯print(open(file).readlines())?」

那麼,你使用它後丟棄文件對象,所以你不能close它。是的,Python最終會自動關閉您的文件,但按照其條款而不是您的文件。如果您只是在shell或終端中玩遊戲,這可能很好,因爲您的會話可能會很短,並且通常不存在任何資源對文件的競爭。但是,在生產環境中,在腳本的整個生命週期中將文件句柄保留爲打開狀態可能會對性能產生破壞性影響。

至於創建一個接收文件對象並寫入它的函數,那麼這基本上就是file.write。考慮一個文件句柄是一個包含方法的對象,並且這些場景後面的方法以self(即對象)作爲第一個參數。所以編寫自己已經是一個函數,它需要一個文件句柄並寫入它!如果你願意,你可以創建其他功能,但你基本上重複了默認行爲,而沒有實際的好處。

考慮你的第一個功能看起來有點像這樣:

def write_to(file_handle, text): 
    return file_handle.write_to(text) 

但如果我叫file_handleself呢?

def write_to(self, text): 
    return self.write(text) 

現在,它看起來像一個方法,而不是一個獨立的功能。事實上,如果你這樣做:

f = open(some_file, 'w') # or 'a' -- some write mode 
write_to = f.write 

你有幾乎相同的功能(只是綁定到特定的file_handle)!

作爲練習,您還可以在Python中創建自己的上下文管理器(與with語句一起使用)。您可以通過定義__enter____exit__來完成此操作。因此從技術上講,你可以重新定義這個問題,以及:

class FileContextManager(): 
    def __init__(self, filename): 
     self.filename = filename 
     self._file = None 

    def __enter__(self): 
     self._file = open(self.filename, 'w') 

    def __exit__(self, type, value, traceback): 
     self._file.close() 

,然後用它喜歡:

with FileContextManager('hello.txt') as filename: 
    filename.write('Hi!') 

,它會做同樣的事情。

所有這一切只是說如果您需要重新實現並添加到默認行爲,Python足夠靈活地完成所有這些工作,但在標準情況下,這樣做並沒有真正的好處。


就你的例子中的程序而言,在微不足道的情況下,幾乎沒有任何錯誤。但是,你缺少與聲明在主函數中使用了一個機會:如果你想一個函數,需要一個文件句柄作爲參數

def main(): 
    with open('file.txt') as filename: 
     while some_condition: 
      filename.write('some text') 
    # file closed here after we fall off the loop then the with context 

if __name__ == '__main__': 
    main() 

def write_stuff(file_handle, text): 
    return file_handle.write(text) 

def main(): 
    with open('file.txt', 'w') as filename: 
     while some_condition: 
      write_stuff(filename, 'some text') 
    # file closed here after we fall off the loop then the with context 

if __name__ == '__main__': 
    main() 

同樣,你可以做很多不同的方式,所以你最想做什麼?什麼是最可讀的?

「我應該在函數中打開一個文件並將指針傳遞給其他人以寫入,還是應該將其聲明爲模塊變量?」

那麼,正如你所看到的,要麼工作。這個問題與上下文高度相關,通常情況下,最佳實踐決定讓文件在最短時間內處於最小合理範圍。因此,什麼需要訪問您的文件?如果模塊中有很多東西,模塊級別的變量或類可能是一個好主意。再次,在微不足道的情況下,就像上面那樣使用with

+0

那麼你對第二個問題有什麼建議。第一個解決方案還是第二 – micheal 2015-02-23 18:41:34

+0

對不起 - 我正在添加第二個例子。我不太清楚你的第二個問題。我的答案的想法是,「這實際上就像讀取和寫入文件一樣簡單,而且你提出的所有事情本質上都是默認情況下的。」什麼阻止你在主函數中使用'with'語句? – 2015-02-23 18:48:32

+0

您正在提供不同的解決方案。爲什麼我會在已經有'with'的時候創建'FileContextManager'。我的觀點是我不能在同一個函數中執行文件操作,我必須爲此創建一個單獨的函數,爲此我必須使用(全局或參數化)文件對象 – micheal 2015-02-23 19:01:36

-3

問題是你在print和()之間放了一個空格。 此代碼的工作好於Python3:

print(open('yourfile.ext').read()) 
+1

這不是父母的帖子所談論的內容。 – Noelkd 2015-02-23 18:35:36

+0

@ Texom512:它可以在python2和three中都有,也可以不帶空格。 – micheal 2015-02-23 18:42:51