使用 Python 迭代多個輸入流中的行
Python 內建的 **open()** 函式以讀/寫模式開啟一個檔案,並在其上執行讀/寫操作。要對多個檔案進行批次處理,需要使用 Python 標準庫的 **fileinput** 模組。此模組提供了一個 Fileinput 類,具有迭代檔案的功能。該模組還定義了用於相同目的的輔助函式。
此模組的主要介面是 **input()** 函式。此函式返回 Fileinput 類的例項。
fileinput.input(files, inplace, mode)
files 引數是一個或多個要逐個讀取的檔案的名稱。每個檔案充當一個生成器,並且可以使用 for 迴圈對其進行迭代。檔案中每一行都將在 Python 控制檯上列印。
>>> for line in fileinput.input('data.txt'): print (line)
files 引數可以是一個包含多個檔案的元組。檔案的內容將依次顯示。
>>> for line in fileinput.input(files=('a.txt', 'b.txt')): print (line)
Fileinput 類也可以在 with 語句中用作上下文管理器。
>>> with fileinput.input(files=('a.txt', 'b.txt')) as f: for line in f: print (line)
fileinput 模組在其內部定義了以下函式。
序號 | 函式 & 描述 |
---|---|
1 | filename() 返回當前正在讀取的檔案的名稱。 |
2 | fileno() 返回檔案描述符整數。 |
3 | lineno() 返回正在讀取的檔案的行號。該數字是累積計數。 |
4 | filelineno() 僅返回當前檔案的行號。 |
5 | isfirstline() 如果正在讀取當前檔案的第一行,則返回 true,否則返回 false |
以下語句列印檔案中每一行以及行號
>>> for line in fileinput.input('books.py'): print ('{}->{}'.format(fileinput.filelineno(), line))
以上程式碼的示例輸出為
1->import sqlite3 2->conn = sqlite3.connect('c:/python36/books.db') 3->cursor = conn.cursor() 4->cursor.execute("SELECT * from books;") 5->print(cursor.fetchall())
以下程式碼列印資料夾中的每個檔名,後跟其中的編號行。在此程式中,使用了 glob() 函式,該函式返回當前路徑中檔案的列表,可選地使用匹配的萬用字元。這裡 glob(‘*.py’) 將返回當前資料夾中所有副檔名為 .py 的檔案的列表。此列表用作 fileinput.input() 函式的 files 引數。
import fileinput, glob, sys for line in fileinput.input(glob.glob("*.py")): if fileinput.isfirstline(): print (fileinput.filename(),'>') sys.stdout.write ("{}.{}".format(fileinput.filelineno(),line))
請注意 isfirstline() 函式的使用。當新檔案迭代開始時,此函式返回 true,並首先列印 fileinput.filename() 函式返回的檔名,然後顯示帶編號的行。例如
1.py > 1.a = 10 2.b = 20 3.print ('addition=',a+b) hello.py > 1.x = 10 2.y = 20 3.z = x+y 4.print ("x+y=",z)
inplace 引數
預設情況下,fileinput.input() 函式的 inplace = False。如果將其設定為 True,則使輸入檔案可寫。
假設有一個名為 'msg.txt' 的檔案,其中包含以下文字。
Hello Python. Good morning
以下程式碼使用 fileinput 模組開啟檔案並就地修改其內容。
>>> for line in fileinput.input(files='msg.txt',inplace = True): line = line.replace('morning', 'evening') sys.stdout.write(line)
'msg.txt' 將顯示所做的更改。