io --- 處理流的核心工具?

源代碼: Lib/io.py


概述?

io 模塊提供了 Python 用于處理各種 I/O 類(lèi)型的主要工具。三種主要的 I/O類(lèi)型分別為: 文本 I/O, 二進(jìn)制 I/O原始 I/O。這些是泛型類(lèi)型,有很多種后端存儲可以用在他們上面。一個(gè)隸屬于任何這些類(lèi)型的具體對象被稱(chēng)作 file object。 其他同類(lèi)的術(shù)語(yǔ)還有 類(lèi)文件對象。

獨立于其類(lèi)別,每個(gè)具體流對象也將具有各種功能:它可以是只讀,只寫(xiě)或讀寫(xiě)。它還可以允許任意隨機訪(fǎng)問(wèn)(向前或向后尋找任何位置),或僅允許順序訪(fǎng)問(wèn)(例如在套接字或管道的情況下)。

所有流對提供給它們的數據類(lèi)型都很敏感。例如將 str 對象給二進(jìn)制流的 write() 方法會(huì )引發(fā) TypeError。將 bytes 對象提供給文本流的 write() 方法也是如此。

在 3.3 版更改: 由于 IOError 現在是 OSError 的別名,因此用于引發(fā) IOError 的操作現在會(huì )引發(fā) OSError 。

文本 I/O?

文本I/O預期并生成 str 對象。這意味著(zhù),無(wú)論何時(shí)后臺存儲是由字節組成的(例如在文件的情況下),數據的編碼和解碼都是透明的,并且可以選擇轉換特定于平臺的換行符。

創(chuàng )建文本流的最簡(jiǎn)單方法是使用 open(),可以選擇指定編碼:

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

內存中文本流也可以作為 StringIO 對象使用:

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

TextIOBase 的文檔中詳細描述了文本流的API

二進(jìn)制 I/O?

二進(jìn)制I/O(也稱(chēng)為緩沖I/O)預期 bytes-like objects 并生成 bytes 對象。不執行編碼、解碼或換行轉換。這種類(lèi)型的流可以用于所有類(lèi)型的非文本數據,并且還可以在需要手動(dòng)控制文本數據的處理時(shí)使用。

創(chuàng )建二進(jìn)制流的最簡(jiǎn)單方法是使用 open(),并在模式字符串中指定 'b'

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

內存中二進(jìn)制流也可以作為 BytesIO 對象使用:

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

BufferedIOBase 的文檔中詳細描述了二進(jìn)制流 API。

其他庫模塊可以提供額外的方式來(lái)創(chuàng )建文本或二進(jìn)制流。參見(jiàn) socket.socket.makefile() 的示例。

原始 I/O?

原始 I/O(也稱(chēng)為 非緩沖 I/O)通常用作二進(jìn)制和文本流的低級構建塊。用戶(hù)代碼直接操作原始流的用法非常罕見(jiàn)。不過(guò),可以通過(guò)在禁用緩沖的情況下以二進(jìn)制模式打開(kāi)文件來(lái)創(chuàng )建原始流:

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

RawIOBase 的文檔中詳細描述了原始流的API

文本編碼格式?

The default encoding of TextIOWrapper and open() is locale-specific (locale.getencoding()).

但是,很多開(kāi)發(fā)者在打開(kāi)以 UTF-8 編碼的文本文件 (例如 JSON, TOML, Markdown 等等...) 時(shí)會(huì )忘記指定編碼格式,因為大多數 Unix 平臺默認使用 UTF-8 語(yǔ)言區域。 這會(huì )導致各種錯誤因為大多數 Windows 用戶(hù)的語(yǔ)言區域編碼格式并不是 UTF-8。 例如:

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

此外,雖然暫時(shí)還沒(méi)有確定的計劃,但 Python 可能會(huì )在未來(lái)將默認的文本文件編碼格式改為 UTF-8。

為此,強烈建議你在打開(kāi)文本文件時(shí)顯式地指定編碼格式。 如果你想要使用 UTF-8,請傳入 encoding="utf-8"。 要使用當前語(yǔ)言區域的編碼格式,encoding="locale" 已在 Python 3.10 中被支持。

When you need to run existing code on Windows that attempts to open UTF-8 files using the default locale encoding, you can enable the UTF-8 mode. See UTF-8 mode on Windows.

選擇性的 EncodingWarning?

3.10 新版功能: 請參閱 PEP 597 了解詳情。

要找出哪里使用了默認語(yǔ)言區域的編碼格式,你可以啟用 -X warn_default_encoding 命令行選項或設置 PYTHONWARNDEFAULTENCODING 環(huán)境變量,這將在使用默認編碼格式時(shí)發(fā)出 EncodingWarning。

如果你提供了使用 open()TextIOWrapper 的 API 并將 encoding=None 作為形參傳入,你可以使用 text_encoding() 以便 API 的調用方在沒(méi)有傳入 encoding 的時(shí)候將發(fā)出 EncodingWarning。 但是,對于新的 API 請考慮默認就使用 UTF-8 (即 encoding="utf-8")。

高階模塊接口?

io.DEFAULT_BUFFER_SIZE?

包含模塊緩沖 I/O 類(lèi)使用的默認緩沖區大小的 int。 在可能的情況下 open() 將使用文件的 blksize(由 os.stat() 獲得)。

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

這是內置的 open() 函數的別名。

open 附帶參數 path、mode、flags 會(huì )引發(fā) 審計事件。

io.open_code(path)?

'rb' 模式打開(kāi)提供的文件。如果目的是將文件內容做為可執行代碼,則應使用此函數。

path 應當為 str 類(lèi)型并且是一個(gè)絕對路徑。

此函數的行為可以由對 PyFile_SetOpenCodeHook() 的先期調用所重載。 但是,如果 pathstr 類(lèi)型并且是一個(gè)絕對路徑,open_code(path) 的行為應當總是與 open(path, 'rb') 一致。 重載此行為的目的是為了給文件附加額外的驗證或預處理。

3.8 新版功能.

io.text_encoding(encoding, stacklevel=2, /)?

這是一個(gè)針對使用 open()TextIOWrapper 的可調用對象的輔助函數并且具有 encoding=None 形參。

This function returns encoding if it is not None. Otherwise, it returns "locale" or "utf-8" depending on UTF-8 Mode.

This function emits an EncodingWarning if sys.flags.warn_default_encoding is true and encoding is None. stacklevel specifies where the warning is emitted. For example:

def read_text(path, encoding=None):
    encoding = io.text_encoding(encoding)  # stacklevel=2
    with open(path, encoding) as f:
        return f.read()

在這個(gè)例子中,將為 read_text() 的調用方發(fā)出 EncodingWarning。

請參閱 文本編碼格式 了解更多信息。

3.10 新版功能.

在 3.11 版更改: text_encoding() returns "utf-8" when UTF-8 mode is enabled and encoding is None.

exception io.BlockingIOError?

這是內置的 BlockingIOError 異常的兼容性別名。

exception io.UnsupportedOperation?

在流上調用不支持的操作時(shí)引發(fā)的繼承 OSErrorValueError 的異常。

參見(jiàn)

sys

包含標準IO流: sys.stdin, sys.stdoutsys.stderr 。

類(lèi)的層次結構?

I/O 流被安排為按類(lèi)的層次結構實(shí)現。 首先是 抽象基類(lèi) (ABC),用于指定流的各種類(lèi)別,然后是提供標準流實(shí)現的具體類(lèi)。

備注

抽象基類(lèi)還提供某些方法的默認實(shí)現,以幫助實(shí)現具體的流類(lèi)。例如 BufferedIOBase 提供了 readinto()readline() 的未優(yōu)化實(shí)現。

I/O層次結構的頂部是抽象基類(lèi) IOBase 。它定義了流的基本接口。但是請注意,對流的讀取和寫(xiě)入之間沒(méi)有分離。如果實(shí)現不支持指定的操作,則會(huì )引發(fā) UnsupportedOperation 。

抽象基類(lèi) RawIOBaseIOBase 的子類(lèi)。它負責將字節讀取和寫(xiě)入流中。 RawIOBase 的子類(lèi) FileIO 提供計算機文件系統中文件的接口。

抽象基類(lèi) BufferedIOBase 繼承了 IOBase ,處理原始二進(jìn)制流( RawIOBase )上的緩沖。其子類(lèi) BufferedWriter 、 BufferedReaderBufferedRWPair 分別緩沖可讀、可寫(xiě)以及可讀寫(xiě)的原始二進(jìn)制流。 BufferedRandom 提供了帶緩沖的可隨機訪(fǎng)問(wèn)流接口。 BufferedIOBase 的另一個(gè)子類(lèi) BytesIO 是內存中字節流。

抽象基類(lèi) TextIOBase 繼承了 IOBase 。它處理可表示文本的流,并處理字符串的編碼和解碼。類(lèi) TextIOWrapper 繼承了 TextIOBase ,是原始緩沖流( BufferedIOBase )的緩沖文本接口。最后, StringIO 是文本的內存流。

參數名不是規范的一部分,只有 open() 的參數才用作關(guān)鍵字參數。

下表總結了抽象基類(lèi)提供的 io 模塊:

抽象基類(lèi)

繼承

抽象方法

Mixin方法和屬性

IOBase

fileno, seek, 和 truncate

close, closed, __enter__, __exit__, flush, isatty, __iter__, __next__, readable, readline, readlines, seekable, tell, writablewritelines

RawIOBase

IOBase

readintowrite

繼承 IOBase 方法, read, 和 readall

BufferedIOBase

IOBase

detach, read, read1, 和 write

繼承 IOBase 方法, readinto, 和 readinto1

TextIOBase

IOBase

detach, read, readline, 和 write

繼承 IOBase 方法, encoding, errors, 和 newlines

I/O 基類(lèi)?

class io.IOBase?

The abstract base class for all I/O classes.

此類(lèi)為許多方法提供了空的抽象實(shí)現,派生類(lèi)可以有選擇地重寫(xiě)。默認實(shí)現代表一個(gè)無(wú)法讀取、寫(xiě)入或查找的文件。

盡管 IOBase 沒(méi)有聲明 read()write() ,因為它們的簽名會(huì )有所不同,但是實(shí)現和客戶(hù)端應該將這些方法視為接口的一部分。此外,當調用不支持的操作時(shí)可能會(huì )引發(fā) ValueError (或 UnsupportedOperation )。

從文件讀取或寫(xiě)入文件的二進(jìn)制數據的基本類(lèi)型為 bytes 。其他 bytes-like objects 也可以作為方法參數。文本I/O類(lèi)使用 str 數據。

請注意,在關(guān)閉的流上調用任何方法(甚至查詢(xún))都是未定義的(undefined)。在這種情況下,實(shí)現可能會(huì )引發(fā) ValueError 。

IOBase (及其子類(lèi))支持迭代器協(xié)議,這意味著(zhù)可以迭代 IOBase 對象以產(chǎn)生流中的行。根據流是二進(jìn)制流(產(chǎn)生字節)還是文本流(產(chǎn)生字符串),行的定義略有不同。請參見(jiàn)下面的 readline() 。

IOBase 也是一個(gè)上下文管理器,因此支持 with 語(yǔ)句。 在這個(gè)示例中,file 將在 with 語(yǔ)句塊執行完成之后被關(guān)閉 --- 即使是發(fā)生了異常:

with open('spam.txt', 'w') as file:
    file.write('Spam and eggs!')

IOBase 提供以下數據屬性和方法:

close()?

刷新并關(guān)閉此流。如果文件已經(jīng)關(guān)閉,則此方法無(wú)效。文件關(guān)閉后,對文件的任何操作(例如讀取或寫(xiě)入)都會(huì )引發(fā) ValueError 。

為方便起見(jiàn),允許多次調用此方法。但是,只有第一個(gè)調用才會(huì )生效。

closed?

如果流已關(guān)閉,則返回 True。

fileno()?

返回流的底層文件描述符(整數)---如果存在。如果 IO 對象不使用文件描述符,則會(huì )引發(fā) OSError 。

flush()?

刷新流的寫(xiě)入緩沖區(如果適用)。這對只讀和非阻塞流不起作用。

isatty()?

如果流是交互式的(即連接到終端/tty設備),則返回 True 。

readable()?

如果可以讀取流,則返回 True 。否則為 False ,且 read() 將引發(fā) OSError 錯誤。

readline(size=- 1, /)?

從流中讀取并返回一行。如果指定了 size,將至多讀取 size 個(gè)字節。

對于二進(jìn)制文件行結束符總是 b'\n';對于文本文件,可以用將 newline 參數傳給 open() 的方式來(lái)選擇要識別的行結束符。

readlines(hint=- 1, /)?

從流中讀取并返回包含多行的列表??梢灾付?hint 來(lái)控制要讀取的行數:如果(以字節/字符數表示的)所有行的總大小超出了 hint 則將不會(huì )讀取更多的行。

0 或更小的 hint 值以及 None,會(huì )被視為沒(méi)有 hint。

請注意使用 for line in file: ... 就足夠對文件對象進(jìn)行迭代了,可以不必調用 file.readlines()。

seek(offset, whence=SEEK_SET, /)?

將流位置修改到給定的字節 offset。 offset 將相對于由 whence 指定的位置進(jìn)行解析。 whence 的默認值為 SEEK_SET。 whence 的可用值有:

  • SEEK_SET0 -- 流的開(kāi)頭(默認值);offset 應為零或正值

  • SEEK_CUR or 1 -- 當前流位置;offset 可以為負值

  • SEEK_END or 2 -- 流的末尾;offset 通常為負值

返回新的絕對位置。

3.1 新版功能: SEEK_* 常量.

3.3 新版功能: 某些操作系統還可支持其他的值,例如 os.SEEK_HOLEos.SEEK_DATA。特定文件的可用值還會(huì )取決于它是以文本還是二進(jìn)制模式打開(kāi)。

seekable()?

如果流支持隨機訪(fǎng)問(wèn)則返回 True。 如為 False,則 seek(), tell()truncate() 將引發(fā) OSError。

tell()?

返回當前流的位置。

truncate(size=None, /)?

將流的大小調整為給定的 size 個(gè)字節(如果未指定 size 則調整至當前位置)。 當前的流位置不變。 這個(gè)調整操作可擴展或減小當前文件大小。 在擴展的情況下,新文件區域的內容取決于具體平臺(在大多數系統上,額外的字節會(huì )填充為零)。 返回新的文件大小。

在 3.5 版更改: 現在Windows在擴展時(shí)將文件填充為零。

writable()?

如果流支持寫(xiě)入則返回 True。 如為 False,則 write()truncate() 將引發(fā) OSError。

writelines(lines, /)?

將行列表寫(xiě)入到流。 不會(huì )添加行分隔符,因此通常所提供的每一行都帶有末尾行分隔符。

__del__()?

為對象銷(xiāo)毀進(jìn)行準備。 IOBase 提供了此方法的默認實(shí)現,該實(shí)現會(huì )調用實(shí)例的 close() 方法。

class io.RawIOBase?

Base class for raw binary streams. It inherits IOBase.

原始二進(jìn)制流通常會(huì )提供對下層 OS 設備或 API 的低層級訪(fǎng)問(wèn),而不是嘗試將其封裝到高層級的基元中(此功能是在更高層級的緩沖二進(jìn)制流和文本流中實(shí)現的,將在下文中描述)。

RawIOBaseIOBase 的現有成員以外還提供了下列方法:

read(size=- 1, /)?

從對象中讀取 size 個(gè)字節并將其返回。 作為一個(gè)便捷選項,如果 size 未指定或為 -1,則返回所有字節直到 EOF。 在其他情況下,僅會(huì )執行一次系統調用。 如果操作系統調用返回字節數少于 size 則此方法也可能返回少于 size 個(gè)字節。

如果返回 0 個(gè)字節而 size 不為零 0,這表明到達文件末尾。 如果處于非阻塞模式并且沒(méi)有更多字節可用,則返回 None。

默認實(shí)現會(huì )轉至 readall()readinto()。

readall()?

從流中讀取并返回所有字節直到 EOF,如有必要將對流執行多次調用。

readinto(b, /)?

將字節數據讀入預先分配的可寫(xiě) bytes-like object b,并返回所讀取的字節數。 例如,b 可以是一個(gè) bytearray。 如果對象處理非阻塞模式并且沒(méi)有更多字節可用,則返回 None。

write(b, /)?

將給定的 bytes-like object b 寫(xiě)入到下層的原始流,并返回所寫(xiě)入的字節數。 這可以少于 b 的總字節數,具體取決于下層原始流的設定,特別是如果它處于非阻塞模式的話(huà)。 如果原始流設為非阻塞并且不能真正向其寫(xiě)入單個(gè)字節時(shí)則返回 None。 調用者可以在此方法返回后釋放或改變 b,因此該實(shí)現應該僅在方法調用期間訪(fǎng)問(wèn) b。

class io.BufferedIOBase?

Base class for binary streams that support some kind of buffering. It inherits IOBase.

RawIOBase 的主要差別在于 read(), readinto()write() 等方法將(分別)嘗試按照要求讀取盡可能多的輸入或是耗盡所有給定的輸出,其代價(jià)是可能會(huì )執行一次以上的系統調用。

除此之外,那些方法還可能引發(fā) BlockingIOError,如果下層的原始數據流處于非阻塞模式并且無(wú)法接受或給出足夠數據的話(huà);不同于對應的 RawIOBase 方法,它們將永遠不會(huì )返回 None。

并且,read() 方法也沒(méi)有轉向 readinto() 的默認實(shí)現。

典型的 BufferedIOBase 實(shí)現不應當繼承自 RawIOBase 實(shí)現,而要包裝一個(gè)該實(shí)現,正如 BufferedWriterBufferedReader 所做的那樣。

BufferedIOBaseIOBase 的現有成員以外還提供或重載了下列數據屬性和方法:

raw?

BufferedIOBase 處理的下層原始流 (RawIOBase 的實(shí)例)。 它不是 BufferedIOBase API 的組成部分并且不存在于某些實(shí)現中。

detach()?

從緩沖區分離出下層原始流并將其返回。

在原始流被分離之后,緩沖區將處于不可用的狀態(tài)。

某些緩沖區例如 BytesIO 并無(wú)可從此方法返回的單獨原始流的概念。 它們將會(huì )引發(fā) UnsupportedOperation。

3.1 新版功能.

read(size=- 1, /)?

讀取并返回最多 size 個(gè)字節。 如果此參數被省略、為 None 或為負值,則讀取并返回所有數據直到 EOF。 如果流已經(jīng)到達 EOF 則返回一個(gè)空的 bytes 對象。

如果此參數為正值,并且下層原始流不可交互,則可能發(fā)起多個(gè)原始讀取以滿(mǎn)足字節計數(直至先遇到 EOF)。 但對于可交互原始流,則將至多發(fā)起一個(gè)原始讀取,并且簡(jiǎn)短的結果并不意味著(zhù)已到達 EOF。

BlockingIOError 會(huì )在下層原始流不處于阻塞模式,并且當前沒(méi)有可用數據時(shí)被引發(fā)。

read1(size=- 1, /)?

通過(guò)至多一次對下層流的 read() (或 readinto()) 方法的調用讀取并返回至多 size 個(gè)字節。 這適用于在 BufferedIOBase 對象之上實(shí)現你自己的緩沖區的情況。

如果 size-1 (默認值),則返回任意數量的字節(多于零字節,除非已到達 EOF)。

readinto(b, /)?

將字節數據讀入預先分配的可寫(xiě) bytes-like object b 并返回所讀取的字節數。 例如,b 可以是一個(gè) bytearray。

類(lèi)似于 read(),可能對下層原始流發(fā)起多次讀取,除非后者為交互式。

BlockingIOError 會(huì )在下層原始流不處于阻塞模式,并且當前沒(méi)有可用數據時(shí)被引發(fā)。

readinto1(b, /)?

將字節數據讀入預先分配的可寫(xiě) bytes-like object b,其中至多使用一次對下層原始流 read() (或 readinto()) 方法的調用。 返回所讀取的字節數。

BlockingIOError 會(huì )在下層原始流不處于阻塞模式,并且當前沒(méi)有可用數據時(shí)被引發(fā)。

3.5 新版功能.

write(b, /)?

寫(xiě)入給定的 bytes-like object b,并返回寫(xiě)入的字節數 (總是等于 b 的字節長(cháng)度,因為如果寫(xiě)入失敗則會(huì )引發(fā) OSError)。 根據具體實(shí)現的不同,這些字節可能被實(shí)際寫(xiě)入下層流,或是出于運行效率和冗余等考慮而暫存于緩沖區。

當處于非阻塞模式時(shí),如果需要將數據寫(xiě)入原始流但它無(wú)法在不阻塞的情況下接受所有數據則將引發(fā) BlockingIOError。

調用者可能會(huì )在此方法返回后釋放或改變 b,因此該實(shí)現應當僅在方法調用期間訪(fǎng)問(wèn) b。

原始文件 I/O?

class io.FileIO(name, mode='r', closefd=True, opener=None)?

代表一個(gè)包含字節數據的 OS 層級文件的原始二進(jìn)制流。 它繼承自 RawIOBase。

name 可以是以下兩項之一:

  • 代表將被打開(kāi)的文件路徑的字符串或 bytes 對象。 在此情況下 closefd 必須為 True (默認值) 否則將會(huì )引發(fā)異常。

  • 代表一個(gè)現有 OS 層級文件描述符的號碼的整數,作為結果的 FileIO 對象將可訪(fǎng)問(wèn)該文件。 當 FileIO 對象被關(guān)閉時(shí)此 fd 也將被關(guān)閉,除非 closefd 設為 False。

mode 可以為 'r', 'w', 'x''a' 分別表示讀?。J模式)、寫(xiě)入、獨占新建或添加。 如果以寫(xiě)入或添加模式打開(kāi)的文件不存在將自動(dòng)新建;當以寫(xiě)入模式打開(kāi)時(shí)文件將先清空。 以新建模式打開(kāi)時(shí)如果文件已存在則將引發(fā) FileExistsError。 以新建模式打開(kāi)文件也意味著(zhù)要寫(xiě)入,因此該模式的行為與 'w' 類(lèi)似。 在模式中附帶 '+' 將允許同時(shí)讀取和寫(xiě)入。

該類(lèi)的 read() (當附帶正值參數調用時(shí)), readinto()write() 方法將只執行一次系統調用。

可以通過(guò)傳入一個(gè)可調用對象作為 opener 來(lái)使用自定義文件打開(kāi)器。 然后通過(guò)調用 opener 并傳入 (name, flags) 來(lái)獲取文件對象所對應的下層文件描述符。 opener 必須返回一個(gè)打開(kāi)文件描述符(傳入 os.open 作為 opener 的結果在功能上將與傳入 None 類(lèi)似)。

新創(chuàng )建的文件是 不可繼承的。

有關(guān) opener 參數的示例,請參見(jiàn)內置函數 open() 。

在 3.3 版更改: 增加了 opener 參數。增加了 'x' 模式。

在 3.4 版更改: 文件現在禁止繼承。

FileIO 在繼承自 RawIOBaseIOBase 的現有成員以外還提供了以下數據屬性和方法:

mode?

構造函數中給定的模式。

name?

文件名。當構造函數中沒(méi)有給定名稱(chēng)時(shí),這是文件的文件描述符。

緩沖流?

相比原始 I/O,緩沖 I/O 流提供了針對 I/O 設備的更高層級接口。

class io.BytesIO(initial_bytes=b'')?

一個(gè)使用內在字節緩沖區的二進(jìn)制流。 它繼承自 BufferedIOBase。 在 close() 方法被調用時(shí)將會(huì )丟棄緩沖區。

可選參數 initial_bytes 是一個(gè)包含初始數據的 bytes-like object。

BytesIO 在繼承自 BufferedIOBaseIOBase 的成員以外還提供或重載了下列方法:

getbuffer()?

返回一個(gè)對應于緩沖區內容的可讀寫(xiě)視圖而不必拷貝其數據。 此外,改變視圖將透明地更新緩沖區內容:

>>>
>>> b = io.BytesIO(b"abcdef")
>>> view = b.getbuffer()
>>> view[2:4] = b"56"
>>> b.getvalue()
b'ab56ef'

備注

只要視圖保持存在,BytesIO 對象就無(wú)法被改變大小或關(guān)閉。

3.2 新版功能.

getvalue()?

返回包含整個(gè)緩沖區內容的 bytes。

read1(size=- 1, /)?

BytesIO 中,這與 read() 相同。

在 3.7 版更改: size 參數現在是可選的。

readinto1(b, /)?

BytesIO 中,這與 readinto() 相同。

3.5 新版功能.

class io.BufferedReader(raw, buffer_size=DEFAULT_BUFFER_SIZE)?

一個(gè)提供對可讀、不可查找的 RawIOBase 原始二進(jìn)制流的高層級訪(fǎng)問(wèn)的緩沖二進(jìn)制流。 它繼承自 BufferedIOBase。

當從此對象讀取數據時(shí),可能會(huì )從下層原始流請求更大量的數據,并存放到內部緩沖區中。 接下來(lái)可以在后續讀取時(shí)直接返回緩沖數據。

根據給定的可讀 raw 流和 buffer_size 創(chuàng )建 BufferedReader 的構造器。 如果省略 buffer_size,則會(huì )使用 DEFAULT_BUFFER_SIZE。

BufferedReader 在繼承自 BufferedIOBaseIOBase 的成員以外還提供或重載了下列方法:

peek(size=0, /)?

從流返回字節數據而不前移位置。 完成此調用將至多讀取一次原始流。 返回的字節數量可能少于或多于請求的數量。

read(size=- 1, /)?

讀取并返回 size 個(gè)字節,如果 size 未給定或為負值,則讀取至 EOF 或是在非阻塞模式下讀取調用將會(huì )阻塞。

read1(size=- 1, /)?

在原始流上通過(guò)單次調用讀取并返回至多 size 個(gè)字節。 如果至少緩沖了一個(gè)字節,則只返回緩沖的字節。 在其他情況下,將執行一次原始流讀取。

在 3.7 版更改: size 參數現在是可選的。

class io.BufferedWriter(raw, buffer_size=DEFAULT_BUFFER_SIZE)?

一個(gè)提供對可寫(xiě)、不可查找的 RawIOBase 原始二進(jìn)制流的高層級訪(fǎng)問(wèn)的緩沖二進(jìn)制流。 它繼承自 BufferedIOBase。

當寫(xiě)入到此對象時(shí),數據通常會(huì )被放入到內部緩沖區中。 緩沖區將在滿(mǎn)足某些條件的情況下被寫(xiě)到下層的 RawIOBase 對象,包括:

  • 當緩沖區對于所有掛起數據而言太小時(shí);

  • flush() 被調用時(shí)

  • 當(為 BufferedRandom 對象)請求 seek() 時(shí);

  • BufferedWriter 對象被關(guān)閉或銷(xiāo)毀時(shí)。

該構造器會(huì )為給定的可寫(xiě) raw 流創(chuàng )建一個(gè) BufferedWriter。 如果未給定 buffer_size,則使用默認的 DEFAULT_BUFFER_SIZE。

BufferedWriter 在繼承自 BufferedIOBaseIOBase 的成員以外還提供或重載了下列方法:

flush()?

將緩沖區中保存的字節數據強制放入原始流。 如果原始流發(fā)生阻塞則應當引發(fā) BlockingIOError。

write(b, /)?

寫(xiě)入 bytes-like object b 并返回寫(xiě)入的字節數。 當處于非阻塞模式時(shí),如果緩沖區需要被寫(xiě)入但原始流發(fā)生阻塞則將引發(fā) BlockingIOError。

class io.BufferedRandom(raw, buffer_size=DEFAULT_BUFFER_SIZE)?

一個(gè)提供對不可查找的 RawIOBase 原始二進(jìn)制流的高層級訪(fǎng)問(wèn)的緩沖二進(jìn)制流。 它繼承自 BufferedReaderBufferedWriter。

該構造器會(huì )為在第一個(gè)參數中給定的可查找原始流創(chuàng )建一個(gè)讀取器和寫(xiě)入器。 如果省略 buffer_size 則使用默認的 DEFAULT_BUFFER_SIZE。

BufferedRandom 能做到 BufferedReaderBufferedWriter 所能做的任何事。 此外,還會(huì )確保實(shí)現 seek()tell()。

class io.BufferedRWPair(reader, writer, buffer_size=DEFAULT_BUFFER_SIZE, /)?

一個(gè)提供對兩個(gè)不可查找的 RawIOBase 原始二進(jìn)制流的高層級訪(fǎng)問(wèn)的緩沖二進(jìn)制流 --- 一個(gè)可讀,另一個(gè)可寫(xiě)。 它繼承自 BufferedIOBase。

readerwriter 分別是可讀和可寫(xiě)的 RawIOBase 對象。 如果省略 buffer_size 則使用默認的 DEFAULT_BUFFER_SIZE。

BufferedRWPair 實(shí)現了 BufferedIOBase 的所有方法,但 detach() 除外,調用該方法將引發(fā) UnsupportedOperation。

警告

BufferedRWPair 不會(huì )嘗試同步訪(fǎng)問(wèn)其下層的原始流。 你不應當將傳給它與讀取器和寫(xiě)入器相同的對象;而要改用 BufferedRandom。

文本 I/O?

class io.TextIOBase?

Base class for text streams. This class provides a character and line based interface to stream I/O. It inherits IOBase.

TextIOBase 在來(lái)自 IOBase 的成員以外還提供或重載了以下數據屬性和方法:

encoding?

用于將流的字節串解碼為字符串以及將字符串編碼為字節串的編碼格式名稱(chēng)。

errors?

解碼器或編碼器的錯誤設置。

newlines?

一個(gè)字符串、字符串元組或者 None,表示目前已經(jīng)轉寫(xiě)的新行。 根據具體實(shí)現和初始構造器旗標的不同,此屬性或許會(huì )不可用。

buffer?

TextIOBase 處理的下層二進(jìn)制緩沖區(為一個(gè) BufferedIOBase 的實(shí)例)。 它不是 TextIOBase API 的組成部分并且不存在于某些實(shí)現中。

detach()?

TextIOBase 分離出下層二進(jìn)制緩沖區并將其返回。

在下層緩沖區被分離后,TextIOBase 將處于不可用的狀態(tài)。

某些 TextIOBase 的實(shí)現,例如 StringIO 可能并無(wú)下層緩沖區的概念,因此調用此方法將引發(fā) UnsupportedOperation。

3.1 新版功能.

read(size=- 1, /)?

從流中讀取至多 size 個(gè)字符并以單個(gè) str 的形式返回。 如果 size 為負值或 None,則讀取至 EOF。

readline(size=- 1, /)?

讀取至換行符或 EOF 并返回單個(gè) str。 如果流已經(jīng)到達 EOF,則將返回一個(gè)空字符串。

如果指定了 size ,最多將讀取 size 個(gè)字符。

seek(offset, whence=SEEK_SET, /)?

將流位置改為給定的偏移位置 offset。 具體行為取決于 whence 形參。 whence 的默認值為 SEEK_SET。

  • SEEK_SET0: 從流的開(kāi)始位置起查找(默認值);offset 必須為 TextIOBase.tell() 所返回的數值或為零。 任何其他 offset 值都將導致未定義的行為。

  • SEEK_CUR1: "查找" 到當前位置;offset 必須為零,表示無(wú)操作(所有其他值均不受支持)。

  • SEEK_END2: 查找到流的末尾;offset 必須為零(所有其他值均不受支持)。

以不透明數字形式返回新的絕對位置。

3.1 新版功能: SEEK_* 常量.

tell()?

以不透明數字形式返回當前流的位置。 該數字通常并不代表下層二進(jìn)制存儲中對應的字節數。

write(s, /)?

將字符串 s 寫(xiě)入到流并返回寫(xiě)入的字符數。

class io.TextIOWrapper(buffer, encoding=None, errors=None, newline=None, line_buffering=False, write_through=False)?

一個(gè)提供對 BufferedIOBase 緩沖二進(jìn)制流的高層級訪(fǎng)問(wèn)的緩沖文本流。 它繼承自 TextIOBase。

encoding gives the name of the encoding that the stream will be decoded or encoded with. It defaults to locale.getencoding(). encoding="locale" can be used to specify the current locale's encoding explicitly. See 文本編碼格式 for more information.

errors 是一個(gè)可選的字符串,它指明編碼格式和編碼格式錯誤的處理方式。 傳入 'strict' 將在出現編碼格式錯誤時(shí)引發(fā) ValueError (默認值 None 具有相同的效果),傳入 'ignore' 將忽略錯誤。 (請注意忽略編碼格式錯誤會(huì )導致數據丟失。) 'replace' 會(huì )在出現錯誤數據時(shí)插入一個(gè)替換標記 (例如 '?')。 'backslashreplace' 將把錯誤數據替換為一個(gè)反斜杠轉義序列。 在寫(xiě)入時(shí),還可以使用 'xmlcharrefreplace' (替換為適當的 XML 字符引用) 或 'namereplace' (替換為 \N{...} 轉義序列)。 任何其他通過(guò) codecs.register_error() 注冊的錯誤處理方式名稱(chēng)也可以被接受。

newline 控制行結束符處理方式。 它可以為 None, '', '\n', '\r''\r\n'。 其工作原理如下:

  • 當從流讀取輸入時(shí),如果 newlineNone,則將啟用 universal newlines 模式。 輸入中的行結束符可以為 '\n', '\r''\r\n',在返回給調用者之前它們會(huì )被統一轉寫(xiě)為 '\n'。 如果 newline'',也會(huì )啟用通用換行模式,但行結束符會(huì )不加轉寫(xiě)即返回給調用者。 如果 newline 具有任何其他合法的值,則輸入行將僅由給定的字符串結束,并且行結束符會(huì )不加轉寫(xiě)即返回給調用者。

  • 將輸出寫(xiě)入流時(shí),如果 newlineNone,則寫(xiě)入的任何 '\n' 字符都將轉換為系統默認行分隔符 os.linesep。如果 newline'''\n',則不進(jìn)行翻譯。如果 newline 是任何其他合法值,則寫(xiě)入的任何 '\n' 字符將被轉換為給定的字符串。

如果 line_bufferingTrue,則當一個(gè)寫(xiě)入調用包含換行符或回車(chē)時(shí)將會(huì )應用 flush()。

如果 write_throughTrue,對 write() 的調用會(huì )確保不被緩沖:在 TextIOWrapper 對象上寫(xiě)入的任何數據會(huì )立即交給其下層的 buffer 來(lái)處理。

在 3.3 版更改: 已添加 write_through 參數

在 3.3 版更改: 默認的 encoding 現在將為 locale.getpreferredencoding(False) 而非 locale.getpreferredencoding()。 不要使用 locale.setlocale() 來(lái)臨時(shí)改變區域編碼格式,要使用當前區域編碼格式而不是用戶(hù)的首選編碼格式。

在 3.10 版更改: encoding 參數現在支持 "locale" 作為編碼格式名稱(chēng)。

TextIOWrapper 在繼承自 TextIOBaseIOBase 的現有成員以外還提供了以下數據屬性和方法:

line_buffering?

是否啟用行緩沖。

write_through?

寫(xiě)入是否要立即傳給下層的二進(jìn)制緩沖。

3.7 新版功能.

reconfigure(*[, encoding][, errors][, newline][,                      line_buffering][, write_through])?

使用 encoding, errors, newline, line_bufferingwrite_through 的新設置來(lái)重新配置此文本流。

未指定的形參將保留當前設定,例外情況是當指定了 encoding 但未指定 errors 時(shí)將會(huì )使用 errors='strict'。

如果已經(jīng)有數據從流中被讀取則將無(wú)法再改變編碼格式或行結束符。 另一方面,在寫(xiě)入數據之后再改變編碼格式則是可以的。

此方法會(huì )在設置新的形參之前執行隱式的流刷新。

3.7 新版功能.

在 3.11 版更改: The method supports encoding="locale" option.

class io.StringIO(initial_value='', newline='\n')?

一個(gè)使用內存文本緩沖的文本流。 它繼承自 TextIOBase。

close() 方法被調用時(shí)將會(huì )丟棄文本緩沖區。

緩沖區的初始值可通過(guò)提供 initial_value 來(lái)設置。 如果啟用了行結束符轉寫(xiě),換行將以 write() 所用的方式被編碼。 數據流位置將被設為緩沖區的開(kāi)頭。

newline 參數的規則與 TextIOWrapper 所用的一致,不同之處在于當將輸出寫(xiě)入到流時(shí),如果 newlineNone,則在所有平臺上換行符都會(huì )被寫(xiě)入為 \n。

StringIO 在繼承自 TextIOBaseIOBase 的現有成員以外還提供了以下方法:

getvalue()?

返回一個(gè)包含緩沖區全部?jì)热莸?str。 換行符會(huì )以與 read() 相同的方式被編碼,但是流的位置不會(huì )被改變。

用法示例:

import io

output = io.StringIO()
output.write('First line.\n')
print('Second line.', file=output)

# Retrieve file contents -- this will be
# 'First line.\nSecond line.\n'
contents = output.getvalue()

# Close object and discard memory buffer --
# .getvalue() will now raise an exception.
output.close()
class io.IncrementalNewlineDecoder?

用于在 universal newlines 模式下解碼換行符的輔助編解碼器。 它繼承自 codecs.IncrementalDecoder。

性能?

本節討論所提供的具體 I/O 實(shí)現的性能。

二進(jìn)制 I/O?

即使在用戶(hù)請求單個(gè)字節時(shí),也只讀取和寫(xiě)入大塊數據。通過(guò)該方法,緩沖 I/O 隱藏了操作系統調用和執行無(wú)緩沖 I/O 例程時(shí)的任何低效性。增益取決于操作系統和執行的 I/O 類(lèi)型。例如,在某些現代操作系統上(例如 Linux),無(wú)緩沖磁盤(pán) I/O 可以與緩沖 I/O 一樣快。但最重要的是,無(wú)論平臺和支持設備如何,緩沖 I/O 都能提供可預測的性能。因此,對于二進(jìn)制數據,應首選使用緩沖的 I/O 而不是未緩沖的 I/O 。

文本 I/O?

二進(jìn)制存儲(如文件)上的文本 I/O 比同一存儲上的二進(jìn)制 I/O 慢得多,因為它需要使用字符編解碼器在Unicode和二進(jìn)制數據之間進(jìn)行轉換。這在處理大量文本數據(如大型日志文件)時(shí)會(huì )變得非常明顯。此外,由于使用的重構算法 TextIOWrapper.tell()TextIOWrapper.seek() 都相當慢。

StringIO 是原生的內存 Unicode 容器,速度與 BytesIO 相似。

多線(xiàn)程?

FileIO 對象是線(xiàn)程安全的,只要它們封裝的操作系統調用(比如Unix下的 read(2) )也是線(xiàn)程安全的。

二進(jìn)制緩沖對象(例如 BufferedReader, BufferedWriter, BufferedRandomBufferedRWPair)使用鎖來(lái)保護其內部結構;因此,可以安全地一次從多個(gè)線(xiàn)程中調用它們。

TextIOWrapper 對象不再是線(xiàn)程安全的。

可重入性?

二進(jìn)制緩沖對象( BufferedReader , BufferedWriter , BufferedRandomBufferedRWPair 的實(shí)例)不是可重入的。雖然在正常情況下不會(huì )發(fā)生可重入調用,但仍可能會(huì )在 signal 處理程序執行 I/O 時(shí)產(chǎn)生。如果線(xiàn)程嘗試重入已經(jīng)訪(fǎng)問(wèn)的緩沖對象,則會(huì )引發(fā) RuntimeError 。注意,這并不禁止其他線(xiàn)程進(jìn)入緩沖對象。

上面的內容隱式地擴展到文本文件中,因為 open() 函數將把緩沖對象封裝在 TextIOWrapper 中。 這包括標準流,因而也會(huì )影響內置的 print() 函數。