fileinput — 迭代多個輸入流中的行

原始碼: Lib/fileinput.py


這個模組實現了一個幫助類和一些函式,可以快速編寫一個迴圈來處理標準輸入或檔案列表。如果只想讀取或寫入一個檔案,請參閱 open()

典型的用法是

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

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

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

在 3.3 版本中更改: 以前引發 IOError;現在它是 OSError 的別名。

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

空檔案將被開啟並立即關閉;它們在檔名列表中存在的唯一可見時間是當最後一個開啟的檔案為空時。

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

你可以透過透過 *openhook* 引數向 fileinput.input()FileInput() 提供一個開啟鉤子來控制檔案的開啟方式。該鉤子必須是一個接受兩個引數的函式:*filename* 和 *mode*,並返回一個相應開啟的類檔案物件。如果指定了 *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 版本中更改: 關鍵字引數 *mode* 和 *openhook* 現在是僅限關鍵字的。

在 3.10 版本中更改: 添加了僅限關鍵字的引數 *encoding* 和 *errors*。

以下函式使用由 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 語句中用作上下文管理器。在這個例子中,即使發生異常,在退出 with 語句後,input 也會被關閉。

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

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

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

在 3.10 版本中更改: 添加了僅限關鍵字的引數 *encoding* 和 *errors*。

在 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 版本中更改: 添加了僅限關鍵字的引數 *encoding* 和 *errors*。

fileinput.hook_encoded(encoding, errors=None)

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

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

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

自 3.10 版本起已棄用: 此函式已被棄用,因為 fileinput.input()FileInput 現在具有 encodingerrors 引數。