fileinput --- 迭代來自多個輸入流的行

原始碼: Lib/fileinput.py


此模組實現了一個輔助類和一些函式,可快速編寫一個迴圈來處理一個或多個檔案列表。如果你只想讀寫一個檔案,請參閱 open()

典型用法:

import fileinput
for line in fileinput.input(encoding="utf-8"):
    process(line)

這將迭代 sys.argv[1:] 中列出的所有檔案的行,如果列表為空,則預設為 sys.stdin。如果檔名為 '-',它也會被替換為 sys.stdin,並且可選引數 modeopenhook 會被忽略。要指定一個替代的檔名列表,請將其作為第一個引數傳遞給 input()。也允許使用單個檔名。

預設所有檔案都以文字模式開啟,但你可以在呼叫 input()FileInput 時指定 mode 引數來覆蓋此行為。如果在開啟或讀取檔案期間發生 I/O 錯誤,會引發 OSError

在 3.3 版更改: 過去會引發 IOError;現在它是 OSError 的別名。

如果 sys.stdin 被使用超過一次,第二次及以後的使用將不會返回任何行,除非是在互動式使用中,或者它已被顯式重置(例如,使用 sys.stdin.seek(0))。

空檔案會被開啟並立即關閉;只有當最後一個開啟的檔案為空時,才能注意到它們在檔名列表中的存在。

返回的行會保留所有換行符,這意味著檔案中的最後一行可能沒有換行符。

你可以透過向 fileinput.input()FileInput()openhook 引數提供一個開啟鉤子來控制檔案的開啟方式。該鉤子必須是一個接受兩個引數(filenamemode)並返回一個相應開啟的類檔案物件的函式。如果指定了 encoding 和/或 errors,它們將作為額外的關鍵字引數傳遞給鉤子。此模組提供了一個 hook_compressed() 來支援壓縮檔案。

以下函式是該模組的主要介面:

fileinput.input(files=None, inplace=False, backup='', *, mode='r', openhook=None, encoding=None, errors=None)

建立 FileInput 類的一個例項。該例項將用作此模組函式的全域性狀態,並且在迭代期間也會返回該例項。此函式的引數將傳遞給 FileInput 類的建構函式。

FileInput 例項可以在 with 語句中用作上下文管理器。在此示例中,即使發生異常,input 也會在 with 語句退出後關閉:

with fileinput.input(files=('spam.txt', 'eggs.txt'), encoding="utf-8") as f:
    for line in f:
        process(line)

在 3.2 版更改: 可以用作上下文管理器。

在 3.8 版更改: 關鍵字引數 modeopenhook 現在是僅限關鍵字引數。

在 3.10 版更改: 添加了僅限關鍵字引數 encodingerrors

以下函式使用由 fileinput.input() 建立的全域性狀態;如果沒有活動狀態,則引發 RuntimeError

fileinput.filename()

返回當前正在讀取的檔案的名稱。在讀取第一行之前,返回 None

fileinput.fileno()

返回當前檔案的整數“檔案描述符”。當沒有檔案開啟時(在第一行之前和檔案之間),返回 -1

fileinput.lineno()

返回剛讀取的行的累積行號。在讀取第一行之前,返回 0。在讀取最後一個檔案的最後一行之後,返回該行的行號。

fileinput.filelineno()

返回當前檔案中的行號。在讀取第一行之前,返回 0。在讀取最後一個檔案的最後一行之後,返回該行在檔案中的行號。

fileinput.isfirstline()

如果剛讀取的行是其檔案的第一行,則返回 True,否則返回 False

fileinput.isstdin()

如果最後一行是從 sys.stdin 讀取的,則返回 True,否則返回 False

fileinput.nextfile()

關閉當前檔案,以便下一次迭代將從下一個檔案(如果有)的第一行開始讀取;未從檔案中讀取的行將不計入累積行數。在讀取下一個檔案的第一行之後,檔名才會更改。在讀取第一行之前,此函式不起作用;它不能用於跳過第一個檔案。在讀取最後一個檔案的最後一行之後,此函式不起作用。

fileinput.close()

關閉序列。

實現模組提供的序列行為的類也可用於子類化:

class fileinput.FileInput(files=None, inplace=False, backup='', *, mode='r', openhook=None, encoding=None, errors=None)

FileInput 類是具體實現;其方法 filename(), fileno(), lineno(), filelineno(), isfirstline(), isstdin(), nextfile()close() 對應於模組中同名的函式。此外,它是一個 可迭代物件,並有一個 readline() 方法,該方法返回下一個輸入行。序列必須以嚴格的順序訪問;隨機訪問和 readline() 不能混合使用。

使用 mode,你可以指定將傳遞給 open() 的檔案模式。它必須是 'r''rb' 之一。

openhook 如果被指定,必須是一個接受兩個引數(filenamemode)的函式,並返回一個相應開啟的類檔案物件。你不能同時使用 inplaceopenhook

你可以指定傳遞給 open()openhookencodingerrors

一個 FileInput 例項可以在 with 語句中用作上下文管理器。在此示例中,即使發生異常,input 也會在 with 語句退出後關閉:

with FileInput(files=('spam.txt', 'eggs.txt')) as input:
    process(input)

在 3.2 版更改: 可以用作上下文管理器。

在 3.8 版更改: 關鍵字引數 modeopenhook 現在是僅限關鍵字引數。

在 3.10 版更改: 添加了僅限關鍵字引數 encodingerrors

在 3.11 版更改: 移除了 'rU''U' 模式以及 __getitem__() 方法。

可選的原地過濾:如果將關鍵字引數 inplace=True 傳遞給 fileinput.input()FileInput 建構函式,檔案將被移動到備份檔案,並且標準輸出將被重定向到輸入檔案(如果已存在與備份檔案同名的檔案,它將被靜默替換)。這使得編寫一個可以原地重寫其輸入檔案的過濾器成為可能。如果給定了 backup 引數(通常是 backup='.<some extension>'),它指定了備份檔案的副檔名,並且備份檔案會保留下來;預設情況下,副檔名為 '.bak',並且在輸出檔案關閉時會被刪除。當讀取標準輸入時,原地過濾是停用的。

此模組提供了以下兩個開啟鉤子:

fileinput.hook_compressed(filename, mode, *, encoding=None, errors=None)

使用 gzipbz2 模組透明地開啟由 gzip 和 bzip2 壓縮的檔案(透過副檔名 '.gz''.bz2' 識別)。如果檔名副檔名不是 '.gz''.bz2',檔案將正常開啟(即,使用 open(),不進行任何解壓)。

encodingerrors 值會傳遞給壓縮檔案的 io.TextIOWrapper 和普通檔案的 open 函式。

用法示例:fi = fileinput.FileInput(openhook=fileinput.hook_compressed, encoding="utf-8")

在 3.10 版更改: 添加了僅限關鍵字引數 encodingerrors

fileinput.hook_encoded(encoding, errors=None)

返回一個鉤子,該鉤子使用 open() 開啟每個檔案,並使用給定的 encodingerrors 來讀取檔案。

用法示例:fi = fileinput.FileInput(openhook=fileinput.hook_encoded("utf-8", "surrogateescape"))

在 3.6 版更改: 添加了可選的 errors 引數。

自 3.10 版起不推薦使用: 此函式已棄用,因為 fileinput.input()FileInput 現在有了 encodingerrors 引數。