2012-02-14 78 views
113

我正在研究如何在Python中執行文件輸入和輸出。我寫了下面的代碼,從一個文件讀取一個名稱列表(每行一個)到另一個文件中,同時檢查文件中名稱的名稱並將文本附加到文件中的出現位置。代碼起作用。它能做得更好嗎?如何使用open語句打開文件

我想爲輸入和輸出文件使用with open(...語句,但看不到它們可能在同一個塊中,這意味着我需要將名稱存儲在臨時位置。

def filter(txt, oldfile, newfile): 
    '''\ 
    Read a list of names from a file line by line into an output file. 
    If a line begins with a particular name, insert a string of text 
    after the name before appending the line to the output file. 
    ''' 

    outfile = open(newfile, 'w') 
    with open(oldfile, 'r', encoding='utf-8') as infile: 
     for line in infile: 
      if line.startswith(txt): 
       line = line[0:len(txt)] + ' - Truly a great person!\n' 
      outfile.write(line) 

    outfile.close() 
    return # Do I gain anything by including this? 

# input the name you want to check against 
text = input('Please enter the name of a great person: ')  
letsgo = filter(text,'Spanish', 'Spanish2') 
+0

「這意味着我需要將名稱存儲在臨時位置」?你能解釋一下你的意思嗎? – 2012-02-14 19:58:50

+2

請注意,filter()是[內建函數](https://docs.python.org/2/library/functions.html#filter),因此您應該爲函數選擇不同的名稱。 – Tom 2017-05-05 19:53:39

+0

@Tom在命名空間中的函數是否覆蓋了內置函數? – UpTide 2017-11-08 19:59:35

回答

195

Python允許將多個open()語句在一個with。你用逗號分開它們。然後,您的代碼將是:

def filter(txt, oldfile, newfile): 
    '''\ 
    Read a list of names from a file line by line into an output file. 
    If a line begins with a particular name, insert a string of text 
    after the name before appending the line to the output file. 
    ''' 

    with open(newfile, 'w') as outfile, open(oldfile, 'r', encoding='utf-8') as infile: 
     for line in infile: 
      if line.startswith(txt): 
       line = line[0:len(txt)] + ' - Truly a great person!\n' 
      outfile.write(line) 

# input the name you want to check against 
text = input('Please enter the name of a great person: ')  
letsgo = filter(text,'Spanish', 'Spanish2') 

不,你不通過將明確return在你的函數結束時獲得任何東西。您可以使用return提前退出,但最後退出,並且該功能將在沒有它的情況下退出。 (當然有返回值的函數,你使用return指定返回值。)

使用多個open()項目進行with在Python 2.5不支持時,在引入with聲明,或在Python 2.6,但它在Python 2.7和Python 3.1或更新版本中受支持。

http://docs.python.org/reference/compound_stmts.html#the-with-statement http://docs.python.org/release/3.1/reference/compound_stmts.html#the-with-statement

如果你正在寫必須在Python 2.5,2.6或3.0運行代碼,嵌套with陳述其他答案建議或使用contextlib.nested

8

你可以嵌套你的塊。就像這樣:

with open(newfile, 'w') as outfile: 
    with open(oldfile, 'r', encoding='utf-8') as infile: 
     for line in infile: 
      if line.startswith(txt): 
       line = line[0:len(txt)] + ' - Truly a great person!\n' 
      outfile.write(line) 

這是不是您的版本更好,因爲你保證outfile會即使您的代碼遇到異常關閉。顯然你可以用try/finally來做到這一點,但with是正確的做法。

或者,據我所知,可以在with語句中使用多個上下文管理器,如described by @steveha。這似乎是比嵌套更好的選擇。

而對於你最後的小問題,回報沒有真正的目的。我會刪除它。

+0

非常感謝。我會試試看,如果/當我得到它的工作,接受你的答案。 – Disnami 2012-02-14 19:29:24

+0

再次感謝。必須等待七個小時才能接受。 – Disnami 2012-02-14 19:35:11

+5

@Disnami確保你接受正確的答案(而且這不是這個!);-) – 2012-02-14 19:41:10

18

使用嵌套塊這樣的,

with open(newfile, 'w') as outfile: 
    with open(oldfile, 'r', encoding='utf-8') as infile: 
    #your logic goes here