io — 處理資料串流的核心工具

原始碼:Lib/io.py


總覽

io 模組替 Python 提供處理各種類型 IO 的主要工具。有三種主要的 IO 類型: 文字 I/O (text I/O)二進位 I/O (binary I/O) 以及原始 I/O (raw I/O)。這些均為泛用 (generic) 類型,且每種類型都可以使用各式後端儲存 (backing store)。任一種屬於這些類型的具體物件稱為 file object。其它常見的名詞還有資料串流 (stream) 以及類檔案物件 (file-like objects)

無論其類型為何,每個具體的資料串流物件也將具有各種能力:唯讀的、只接受寫入的、或者讀寫兼具的。它還允許任意的隨機存取(向前或向後尋找至任意位置),或者只能依順序存取(例如 socket 或 pipe 的情形下)。

所有的資料串流都會謹慎處理你所提供的資料的型別。舉例來說,提供一個 str 物件給二進位資料串流的 write() 方法將會引發 TypeError。同樣地,若提供一個 bytes 物件給文字資料串流的 write() 方法,也會引發同樣的錯誤。

在 3.3 版的變更: 原本會引發 IOError 的操作,現在將改成引發 OSError。因為 IOError 現在是 OSError 的別名。

文字 I/O

文字 I/O 要求和產出 str 物件。這意味著每當後端儲存為原生 bytes 時(例如在檔案的情形下),資料的編碼與解碼會以清楚易懂的方式進行,也可選擇同時轉換特定於平台的換行字元。

建立文字資料串流最簡單的方法是使用 open(),可選擇性地指定編碼:

f = open("myfile.txt", "r", encoding="utf-8")

記憶體內的文字資料串流也可以使用 StringIO 物件建立:

f = io.StringIO("some initial text data")

備註

When working with a non-blocking stream, be aware that read operations on text I/O objects might raise a BlockingIOError if the stream cannot perform the operation immediately.

文字資料串流 API 的詳細說明在 TextIOBase 文件當中。

二進位 (Binary) I/O

二進位 I/O(也稱為緩衝 I/O (buffered I/O))要求的是類位元組物件 (bytes-like objects) 且產生 bytes 物件。不進行編碼、解碼或者換行字元轉換。這種類型的資料串流可用於各種非文字資料,以及需要手動控制對文字資料的處理時。

建立二進位資料串流最簡單的方法是使用 open(),並在 mode 字串中加入 'b'

f = open("myfile.jpg", "rb")

記憶體內的二進位資料串流也可以透過 BytesIO 物件來建立:

f = io.BytesIO(b"some initial binary data: \x00\x01")

二進位資料串流 API 的詳細說明在 BufferedIOBase 文件當中。

其它函式庫模組可能提供額外的方法來建立文字或二進位資料串流。例如 socket.socket.makefile()

原始 (Raw) I/O

原始 I/O(也稱為無緩衝 I/O (unbuffered I/O))通常作為二進位以及文字資料串流的低階 building-block 使用;在使用者程式碼中直接操作原始資料串流很少有用。然而,你可以透過以無緩衝的二進位模式開啟一個檔案來建立一個原始資料串流:

f = open("myfile.jpg", "rb", buffering=0)

原始串流 API 在 RawIOBase 文件中有詳細描述。

文字編碼

TextIOWrapperopen() 預設編碼是根據區域設定的 (locale-specific) (locale.getencoding())。

然而,許多開發人員在開啟以 UTF-8 編碼的文字檔案(例如:JSON、TOML、Markdown等)時忘記指定編碼,因為多數 Unix 平台預設使用 UTF-8 區域設定。這會導致錯誤,因為對於大多數 Windows 使用者來說,預設地區編碼並非 UTF-8。舉例來說:

# May not work on Windows when non-ASCII characters in the file.
with open("README.md") as f:
    long_description = f.read()

因此,強烈建議在開啟文字檔案時,明確指定編碼。若你想使用 UTF-8 編碼,請傳入 encoding="utf-8"。若想使用目前的地區編碼,Python 3.10 以後的版本支援使用 encoding="locale"

也參考

Python UTF-8 模式

在 Python UTF-8 模式下,可以將預設編碼從特定地區編碼改為 UTF-8。

PEP 686

Python 3.15 將預設使用 Python UTF-8 模式

選擇性加入的編碼警告

在 3.10 版被加入: 更多資訊請見 PEP 597

要找出哪些地方使用到預設的地區編碼,你可以啟用 -X warn_default_encoding 命令列選項,或者設定環境變數 PYTHONWARNDEFAULTENCODING。當使用到預設編碼時,會引發 EncodingWarning

如果你正在提供一個使用 open()TextIOWrapper 且傳遞 encoding=None 作為參數的 API,你可以使用 text_encoding()。如此一來如果 API 的呼叫方沒有傳遞 encoding,呼叫方就會發出一個 EncodingWarning。然而,對於新的 API,請考慮預設使用 UTF-8(即 encoding="utf-8")。

高階模組介面

io.DEFAULT_BUFFER_SIZE

一個包含模組中緩衝 I/O 類別所使用的預設緩衝區大小的整數。若可能的話,open() 會使用檔案的 blksize (透過 os.stat() 取得)。

io.open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

這是內建函式 open() 的別名。

此函式會引發一個帶有引數 pathmode 以及 flags稽核事件 (auditing event) openmodeflags 引數可能已經被修改或者從原始呼叫中被推斷出來。

io.open_code(path)

'rb' 模式開啟提供的檔案。此函式應用於意圖將內容視為可執行的程式碼的情況下。

path 應該要屬於