io
— 用於處理流的核心工具¶
原始碼: Lib/io.py
概述¶
io
模組提供了 Python 用於處理各種 I/O 型別的主要工具。主要有三種 I/O 型別:文字 I/O、二進位制 I/O 和 原始 I/O。這些是通用類別,每種類別都可以使用各種後備儲存。屬於這些類別中任何一個的具體物件都稱為檔案物件。其他常用術語是流和類檔案物件。
每個具體的流物件,無論其類別如何,也都將具有各種功能:它可以是隻讀的、只寫的或讀寫的。它還可以允許任意隨機訪問(向前或向後查詢任何位置),或者僅允許順序訪問(例如,在套接字或管道的情況下)。
所有流都對其接收的資料型別非常注意。例如,將str
物件傳遞給二進位制流的 write()
方法將引發 TypeError
。同樣,將bytes
物件傳遞給文字流的 write()
方法也會引發此錯誤。
文字 I/O¶
文字 I/O 預期並生成 str
物件。這意味著,當後備儲存本身由位元組組成時(例如在檔案的情況下),資料的編碼和解碼會透明地進行,並且可以選擇性地轉換特定於平臺的新行字元。
建立文字流的最簡單方法是使用 open()
,可以選擇指定編碼
f = open("myfile.txt", "r", encoding="utf-8")
記憶體中文字流也可以作為 StringIO
物件使用
f = io.StringIO("some initial text data")
文字流 API 在 TextIOBase
的文件中有詳細描述。
二進位制 I/O¶
二進位制 I/O(也稱為緩衝 I/O)預期 類位元組物件 並生成 bytes
物件。不執行編碼、解碼或新行轉換。此類別流可用於所有型別的非文字資料,並且在需要手動控制文字資料處理時也可使用。
建立二進位制流的最簡單方法是使用 open()
,並在模式字串中使用 'b'
f = open("myfile.jpg", "rb")
記憶體中的二進位制流也可以作為 BytesIO
物件使用
f = io.BytesIO(b"some initial binary data: \x00\x01")
二進位制流 API 在 BufferedIOBase
的文件中有詳細描述。
其他庫模組可能會提供建立文字或二進位制流的其他方法。例如,請參閱 socket.socket.makefile()
。
原始 I/O¶
原始 I/O(也稱為無緩衝 I/O)通常用作二進位制和文字流的底層構建塊;直接從使用者程式碼操作原始流很少有用。但是,您可以透過在停用緩衝的情況下以二進位制模式開啟檔案來建立原始流
f = open("myfile.jpg", "rb", buffering=0)
原始流 API 在 RawIOBase
的文件中有詳細描述。
文字編碼¶
TextIOWrapper
和 open()
的預設編碼是特定於區域設定的 (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 模式 成為預設模式。
選擇啟用 EncodingWarning¶
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.open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)¶
這是內建
open()
函式的別名。此函式會引發一個 審計事件
open
,其引數為 path、mode 和 flags。mode 和 flags 引數可能已被修改或從原始呼叫中推斷出來。
- io.open_code(path)¶
以模式
'rb'
開啟提供的檔案。當意圖將內容視為可執行程式碼時,應使用此函式。path 應該是一個
str
且是絕對路徑。此函式的行為可能會被之前對
PyFile_SetOpenCodeHook()
的呼叫覆蓋。但是,假設 path 是一個str
且是絕對路徑,則open_code(path)
的行為應始終與open(path, 'rb')
相同。覆蓋該行為旨在對檔案進行額外的驗證或預處理。3.8 版本中新增。
- io.text_encoding(encoding, stacklevel=2, /)¶
這是一個輔助函式,用於使用
open()
或TextIOWrapper
並且具有encoding=None
引數的可呼叫物件。如果 encoding 不是
None
,則此函式返回 encoding。 否則,它將根據 UTF-8 模式 返回"locale"
或"utf-8"
。如果
sys.flags.warn_default_encoding
為 true 且 encoding 為None
,則此函式會發出EncodingWarning
。stacklevel 指定發出警告的位置。例如def read_text(path, encoding=None): encoding = io.text_encoding(encoding) # stacklevel=2 with open(path, encoding) as f: return f.read()
在此示例中,將為
read_text()
的呼叫者發出EncodingWarning
。有關更多資訊,請參閱 文字編碼。
3.10 版本中新增。
在 3.11 版本中更改: 當啟用 UTF-8 模式且 encoding 為
None
時,text_encoding()
返回 "utf-8"。
- exception io.BlockingIOError¶
這是內建
BlockingIOError
異常的相容性別名。
- exception io.UnsupportedOperation¶
當在流上呼叫不支援的操作時引發的繼承自
OSError
和ValueError
的異常。
另請參閱
sys
包含標準 IO 流:
sys.stdin
、sys.stdout
和sys.stderr
。
類層次結構¶
I/O 流的實現組織為類層次結構。 首先是 抽象基類 (ABCs),用於指定各種類別的流,然後是提供標準流實現的具體類。
注意
抽象基類還提供一些方法的預設實現,以幫助實現具體的流類。例如,BufferedIOBase
提供了 readinto()
和 readline()
的未最佳化實現。
在 I/O 層次結構的頂部是抽象基類 IOBase
。 它定義了流的基本介面。但是,請注意,流的讀取和寫入之間沒有分離;如果實現不支援給定的操作,則允許引發 UnsupportedOperation
。
RawIOBase
ABC 擴充套件了 IOBase
。 它處理將位元組讀取和寫入到流。 FileIO
子類化 RawIOBase
,以提供對機器檔案系統中檔案的介面。
BufferedIOBase
ABC 擴充套件了 IOBase
。 它處理原始二進位制流 ( RawIOBase
) 上的緩衝。它的子類 BufferedWriter
、BufferedReader
和 BufferedRWPair
分別緩衝可寫、可讀以及既可讀又可寫的原始二進位制流。BufferedRandom
提供了可搜尋流的緩衝介面。 另一個 BufferedIOBase
子類 BytesIO
是記憶體中位元組的流。
TextIOBase
ABC 擴充套件了 IOBase
。它處理位元組表示文字的流,並處理字串的編碼和解碼。TextIOWrapper
,它擴充套件了 TextIOBase
,是緩衝原始流 (BufferedIOBase
) 的緩衝文字介面。最後,StringIO
是用於文字的記憶體流。
引數名稱不是規範的一部分,只有 open()
的引數才可以用作關鍵字引數。
下表總結了 io
模組提供的 ABC
ABC |
繼承自 |
存根方法 |
混入方法和屬性 |
---|---|---|---|
|
|
||
|
繼承的 |
||
|
繼承的 |
||
|
繼承的 |
I/O 基類¶
- class io.IOBase¶
所有 I/O 類的抽象基類。
此類為派生類可以選擇性覆蓋的許多方法提供了空的抽象實現;預設實現表示一個無法讀取、寫入或定位的檔案。
儘管
IOBase
沒有宣告read()
或write()
因為它們的簽名會有所不同,但實現和客戶端應將這些方法視為介面的一部分。此外,當呼叫它們不支援的操作時,實現可能會引發ValueError
(或UnsupportedOperation
)。從檔案讀取或寫入的二進位制資料基本型別是
bytes
。其他 類位元組物件 也被接受為方法引數。文字 I/O 類使用str
資料。請注意,在關閉的流上呼叫任何方法(甚至查詢)都是未定義的。在這種情況下,實現可能會引發
ValueError
。IOBase
(及其子類) 支援迭代器協議,這意味著可以迭代IOBase
物件,以生成流中的行。行的定義略有不同,具體取決於流是二進位制流(生成位元組)還是文字流(生成字串)。請參閱下面的readline()
。IOBase
也是一個上下文管理器,因此支援with
語句。在此示例中,在with
語句的套件完成後,即使發生異常,file 也會關閉with open('spam.txt', 'w') as file: file.write('Spam and eggs!')
IOBase
提供以下資料屬性和方法- close()¶
重新整理並關閉此流。如果檔案已關閉,則此方法無效。檔案關閉後,對檔案的任何操作(例如讀取或寫入)都將引發
ValueError
。為了方便起見,允許多次呼叫此方法;但是,只有第一次呼叫才有效。
- closed¶
如果流已關閉,則為
True
。
- flush()¶
如果適用,則重新整理流的寫入緩衝區。這對只讀和非阻塞流沒有任何作用。
- isatty()¶
如果流是互動式的(即,連線到終端/tty 裝置),則返回
True
。
- readline(size=-1, /)¶
從流中讀取並返回一行。如果指定了 size,則最多讀取 size 個位元組。
對於二進位制檔案,行終止符始終是
b'\n'
;對於文字檔案,可以使用open()
的 newline 引數來選擇識別的行終止符。
- readlines(hint=-1, /)¶
從流中讀取並返回一個行列表。可以指定 hint 來控制讀取的行數:如果到目前為止所有行的總大小(以位元組/字元為單位)超過 hint,則不會讀取更多行。
hint 值為
0
或更小,以及None
,都被視為沒有提示。請注意,已經可以使用
for line in file: ...
來迭代檔案物件,而無需呼叫file.readlines()
。
- seek(offset, whence=os.SEEK_SET, /)¶
將流位置更改為給定的位元組 offset,該 offset 相對於 whence 指示的位置進行解釋,並返回新的絕對位置。 whence 的值是:
os.SEEK_SET
或0
– 流的開始位置(預設);offset 應為零或正數os.SEEK_CUR
或1
– 當前流位置;offset 可以為負數os.SEEK_END
或2
– 流的末尾;offset 通常為負數
3.1 版本新增:
SEEK_*
常量。3.3 版本新增: 一些作業系統可能支援其他值,例如
os.SEEK_HOLE
或os.SEEK_DATA
。檔案的有效值可能取決於它是以文字模式還是二進位制模式開啟的。
- seekable()¶
如果流支援隨機訪問,則返回
True
。 如果為False
,則seek()
、tell()
和truncate()
將引發OSError
。
- tell()¶
返回當前的流位置。
- truncate(size=None, /)¶
將流的大小調整為給定的位元組 size (如果未指定 size,則調整為當前位置)。當前流位置不會更改。這種調整大小可以擴大或縮小當前檔案大小。如果擴充套件,則新檔案區域的內容取決於平臺(在大多數系統上,額外的位元組將填充零)。返回新的檔案大小。
在 3.5 版本中更改: Windows 現在會在擴充套件檔案時填充零。
- writable()¶
如果流支援寫入,則返回
True
。如果為False
,則write()
和truncate()
將引發OSError
。
- writelines(lines, /)¶
將行列表寫入流。不會新增行分隔符,因此通常提供的每一行末尾都有一個行分隔符。
- class io.RawIOBase¶
原始二進位制流的基類。它繼承自
IOBase
。原始二進位制流通常提供對底層作業系統裝置或 API 的低階訪問,並且不會嘗試將其封裝在高階原語中(此功能在緩衝的二進位制流和文字流的更高級別上完成,稍後在本頁中描述)。
RawIOBase
除了來自IOBase
的方法之外,還提供這些方法:- read(size=-1, /)¶
從物件中讀取最多 size 個位元組並返回它們。為方便起見,如果未指定 size 或為 -1,則返回直到 EOF 的所有位元組。否則,只會進行一次系統呼叫。如果作業系統呼叫返回的位元組少於 size 個位元組,則可能返回少於 size 個位元組。
如果返回 0 個位元組,並且 size 不為 0,則表示檔案結束。如果物件處於非阻塞模式並且沒有可用的位元組,則返回
None
。預設實現會延遲到
readall()
和readinto()
。
- readall()¶
讀取並返回流中直到 EOF 的所有位元組,如有必要,可以使用對流的多次呼叫。
- class io.BufferedIOBase¶
支援某種緩衝的二進位制流的基類。它繼承自
IOBase
。與
RawIOBase
的主要區別在於,方法read()
、readinto()
和write()
將嘗試(分別)讀取請求的儘可能多的輸入或消耗所有給定的輸出,代價可能是進行多次系統呼叫。此外,如果底層原始流處於非阻塞模式且無法獲取或提供足夠的資料,這些方法可能會引發
BlockingIOError
異常;與它們的RawIOBase
對應方法不同,它們永遠不會返回None
。此外,
read()
方法沒有預設實現來委託給readinto()
。一個典型的
BufferedIOBase
實現不應繼承自RawIOBase
實現,而是應該像BufferedWriter
和BufferedReader
那樣包裝一個。BufferedIOBase
除了提供或覆蓋來自IOBase
的資料屬性和方法外,還提供或覆蓋以下資料屬性和方法。- raw¶
BufferedIOBase
處理的底層原始流(RawIOBase
例項)。 這不是BufferedIOBase
API 的一部分,可能在某些實現中不存在。
- detach()¶
將底層原始流與緩衝區分離並返回。
在分離原始流後,緩衝區處於不可用狀態。
某些緩衝區,如
BytesIO
,沒有從該方法返回的單個原始流的概念。它們會引發UnsupportedOperation
異常。在 3.1 版本中新增。
- read(size=-1, /)¶
讀取並返回最多 size 個位元組。如果省略該引數,或為
None
或負數,則會讀取並返回資料,直到到達 EOF。如果流已到達 EOF,則返回一個空的bytes
物件。如果引數為正數,並且底層原始流不是互動式的,則可能會發出多次原始讀取以滿足位元組計數(除非先到達 EOF)。但是對於互動式原始流,最多隻會發出一次原始讀取,並且結果較短並不意味著 EOF 即將到來。
如果底層原始流處於非阻塞模式,並且目前沒有可用資料,則會引發
BlockingIOError
異常。
- read1(size=-1, /)¶
讀取並返回最多 size 個位元組,最多呼叫一次底層原始流的
read()
(或readinto()
)方法。如果您正在BufferedIOBase
物件之上實現自己的緩衝,這將非常有用。如果 size 為
-1
(預設值),則返回任意數量的位元組(除非到達 EOF,否則大於零)。
- readinto(b, /)¶
將位元組讀取到預先分配的可寫 類位元組物件 b 中,並返回讀取的位元組數。例如,b 可以是一個
bytearray
。與
read()
類似,可能會向底層原始流發出多次讀取,除非後者是互動式的。如果底層原始流處於非阻塞模式,並且目前沒有可用資料,則會引發
BlockingIOError
異常。
- readinto1(b, /)¶
使用最多一次呼叫底層原始流的
read()
(或readinto()
)方法,將位元組讀取到預先分配的可寫 類位元組物件 b 中。返回讀取的位元組數。如果底層原始流處於非阻塞模式,並且目前沒有可用資料,則會引發
BlockingIOError
異常。在 3.5 版本中新增。
- write(b, /)¶
寫入給定的 類位元組物件 b,並返回寫入的位元組數(始終等於 b 的位元組長度,因為如果寫入失敗,則會引發
OSError
異常)。根據實際實現,這些位元組可能會立即寫入到底層流中,或者為了效能和延遲原因而儲存在緩衝區中。在非阻塞模式下,如果需要將資料寫入原始流,但它無法在不阻塞的情況下接收所有資料,則會引發
BlockingIOError
異常。呼叫者可以在此方法返回後釋放或更改 b,因此實現應僅在方法呼叫期間訪問 b。
原始檔案 I/O¶
- class io.FileIO(name, mode='r', closefd=True, opener=None)¶
表示包含位元組資料的作業系統級檔案的原始二進位制流。它繼承自
RawIOBase
。name 可以是以下兩種情況之一:
表示要開啟的檔案的路徑的字串或
bytes
物件。在這種情況下,closefd 必須為True
(預設值),否則會引發錯誤。一個整數,表示現有作業系統級檔案描述符的編號,生成的
FileIO
物件將允許訪問該描述符。當 FileIO 物件關閉時,此 fd 也將關閉,除非將 closefd 設定為False
。
模式可以是
'r'
、'w'
、'x'
或'a'
,分別表示讀取(預設)、寫入、獨佔建立或追加。當以寫入或追加模式開啟時,如果檔案不存在,則會建立該檔案;當以寫入模式開啟時,檔案會被截斷。如果以建立模式開啟時檔案已存在,則會引發FileExistsError
異常。以建立模式開啟檔案意味著寫入,因此此模式的行為類似於'w'
。在模式中新增'+'
可以允許同時進行讀取和寫入。此類的
read()
(當使用正引數呼叫時)、readinto()
和write()
方法只會進行一次系統呼叫。可以透過傳遞一個可呼叫物件作為 opener 來使用自定義的開啟器。然後透過呼叫 opener 並傳入 (name, flags) 來獲取檔案物件的基礎檔案描述符。 opener 必須返回一個開啟的檔案描述符(將
os.open
作為 opener 傳遞會導致與傳遞None
類似的功能)。新建立的檔案是不可繼承的。
有關使用 opener 引數的示例,請參閱
open()
內建函式。在 3.3 版本中更改: 添加了 opener 引數。添加了
'x'
模式。在 3.4 版本中更改: 檔案現在是不可繼承的。
FileIO
除了來自RawIOBase
和IOBase
的屬性外,還提供以下資料屬性- mode¶
建構函式中給定的模式。
- name¶
檔名。當建構函式中沒有給出名稱時,這是檔案的檔案描述符。
緩衝流¶
緩衝 I/O 流為 I/O 裝置提供了比原始 I/O 更高階的介面。
- class io.BytesIO(initial_bytes=b'')¶
一個使用記憶體位元組緩衝區的二進位制流。它繼承自
BufferedIOBase
。當呼叫close()
方法時,緩衝區將被丟棄。可選引數 initial_bytes 是一個 類位元組物件,其中包含初始資料。
BytesIO
除了來自BufferedIOBase
和IOBase
的方法外,還提供或覆蓋以下方法- getbuffer()¶
返回緩衝區內容的讀寫檢視,而無需複製它們。此外,更改檢視將透明地更新緩衝區的內容
>>> b = io.BytesIO(b"abcdef") >>> view = b.getbuffer() >>> view[2:4] = b"56" >>> b.getvalue() b'ab56ef'
注意
只要檢視存在,就不能調整
BytesIO
物件的大小或關閉它。在 3.2 版本中新增。
- readinto1(b, /)¶
在
BytesIO
中,這與readinto()
相同。在 3.5 版本中新增。
- class io.BufferedReader(raw, buffer_size=DEFAULT_BUFFER_SIZE)¶
一個緩衝的二進位制流,為可讀、不可查詢的
RawIOBase
原始二進位制流提供更高級別的訪問。它繼承自BufferedIOBase
。當從此物件讀取資料時,可能會從底層原始流請求更多的資料,並將其儲存在內部緩衝區中。然後,可以在後續讀取中直接返回緩衝的資料。
建構函式為給定的可讀 raw 流和 buffer_size 建立一個
BufferedReader
。如果省略 buffer_size,則使用DEFAULT_BUFFER_SIZE
。BufferedReader
除了來自BufferedIOBase
和IOBase
的方法外,還提供或覆蓋以下方法- peek(size=0, /)¶
從流返回位元組,而不推進位置。為了滿足呼叫,最多隻對原始流進行一次讀取。返回的位元組數可能少於或多於請求的位元組數。
- read(size=-1, /)¶
讀取並返回 size 個位元組,如果未給定 size 或為負數,則讀取到 EOF 或如果讀取呼叫在非阻塞模式下會阻塞。
- read1(size=-1, /)¶
讀取並返回最多 size 個位元組,僅對原始流進行一次呼叫。如果至少緩衝了一個位元組,則僅返回緩衝的位元組。否則,將進行一次原始流讀取呼叫。
在 3.7 版本中更改: size 引數現在是可選的。
- class io.BufferedWriter(raw, buffer_size=DEFAULT_BUFFER_SIZE)¶
一個緩衝的二進位制流,為可寫、不可查詢的
RawIOBase
原始二進位制流提供更高級別的訪問。它繼承自BufferedIOBase
。當寫入此物件時,資料通常會放入內部緩衝區中。在各種條件下,緩衝區將被寫出到底層的
RawIOBase
物件,包括:當緩衝區對於所有待處理資料來說太小時;
當呼叫
flush()
時;當請求
seek()
時(對於BufferedRandom
物件);當
BufferedWriter
物件關閉或銷燬時。
建構函式為給定的可寫原始流建立一個
BufferedWriter
。如果未給出buffer_size,則預設為DEFAULT_BUFFER_SIZE
。BufferedWriter
除了BufferedIOBase
和IOBase
的方法外,還提供或覆蓋了以下方法:- flush()¶
強制將緩衝區中儲存的位元組寫入原始流。如果原始流阻塞,則應引發
BlockingIOError
異常。
- write(b, /)¶
寫入 位元組類物件b,並返回寫入的位元組數。在非阻塞模式下,如果緩衝區需要寫出但原始流阻塞,則會引發
BlockingIOError
異常。
- class io.BufferedRandom(raw, buffer_size=DEFAULT_BUFFER_SIZE)¶
一個緩衝的二進位制流,提供對可查詢的
RawIOBase
原始二進位制流的高階訪問。它繼承自BufferedReader
和BufferedWriter
。建構函式為可查詢的原始流建立一個讀取器和寫入器,該原始流在第一個引數中給出。如果省略了 buffer_size,則預設為
DEFAULT_BUFFER_SIZE
。BufferedRandom
能夠執行BufferedReader
或BufferedWriter
可以做的任何事情。此外,保證實現seek()
和tell()
。
- class io.BufferedRWPair(reader, writer, buffer_size=DEFAULT_BUFFER_SIZE, /)¶
一個緩衝的二進位制流,提供對兩個不可查詢的
RawIOBase
原始二進位制流(一個可讀,另一個可寫)的高階訪問。它繼承自BufferedIOBase
。reader 和 writer 是
RawIOBase
物件,分別可讀和可寫。如果省略了 buffer_size,則預設為DEFAULT_BUFFER_SIZE
。BufferedRWPair
實現了BufferedIOBase
的所有方法,但detach()
除外,該方法會引發UnsupportedOperation
異常。警告
BufferedRWPair
不會嘗試同步對其底層原始流的訪問。您不應將其作為讀取器和寫入器傳遞相同的物件;請改用BufferedRandom
。
文字 I/O¶
- class io.TextIOBase¶
文字流的基類。此類提供基於字元和行的流 I/O 介面。它繼承自
IOBase
。TextIOBase
除了IOBase
的資料屬性和方法外,還提供或覆蓋了以下資料屬性和方法:- encoding¶
用於將流的位元組解碼為字串以及將字串編碼為位元組的編碼名稱。
- errors¶
解碼器或編碼器的錯誤設定。
- newlines¶
一個字串、一個字串元組或
None
,表示到目前為止轉換的換行符。根據實現和初始建構函式標誌,這可能不可用。
- buffer¶
TextIOBase
處理的底層二進位制緩衝區(一個BufferedIOBase
例項)。這不是TextIOBase
API 的一部分,並且可能在某些實現中不存在。
- detach()¶
將底層二進位制緩衝區與
TextIOBase
分離並返回它。分離底層緩衝區後,
TextIOBase
處於不可用狀態。一些
TextIOBase
實現(如StringIO
)可能沒有底層緩衝區的概念,呼叫此方法會引發UnsupportedOperation
異常。在 3.1 版本中新增。
- seek(offset, whence=SEEK_SET, /)¶
將流位置更改為給定的 offset。行為取決於 whence 引數。whence 的預設值為
SEEK_SET
。SEEK_SET
或0
:從流的開頭開始查詢(預設);offset 必須是TextIOBase.tell()
返回的數字或零。任何其他 offset 值都會產生未定義的行為。SEEK_CUR
或1
: “seek” 到當前位置;offset 必須為零,這是一個空操作(不支援所有其他值)。SEEK_END
或2
: seek 到流的末尾;offset 必須為零(不支援所有其他值)。
返回新的絕對位置,表示為一個不透明的數字。
3.1 版本新增:
SEEK_*
常量。
- tell()¶
返回當前流的位置,表示為一個不透明的數字。該數字通常不代表底層二進位制儲存中的位元組數。
- write(s, /)¶
將字串 s 寫入流並返回寫入的字元數。
- class io.TextIOWrapper(buffer, encoding=None, errors=None, newline=None, line_buffering=False, write_through=False)¶
一個緩衝的文字流,為
BufferedIOBase
緩衝的二進位制流提供更高級別的訪問。它繼承自TextIOBase
。encoding 指定流將使用哪種編碼進行解碼或編碼。預設為
locale.getencoding()
。 可以使用encoding="locale"
來顯式指定當前區域設定的編碼。有關更多資訊,請參見 文字編碼。errors 是一個可選的字串,用於指定如何處理編碼和解碼錯誤。如果存在編碼錯誤,則傳遞
'strict'
來引發ValueError
異常(None
的預設值具有相同的效果),或者傳遞'ignore'
來忽略錯誤。(請注意,忽略編碼錯誤可能會導致資料丟失。)'replace'
會在存在格式錯誤的資料時插入一個替換標記(例如'?'
)。'backslashreplace'
會將格式錯誤的資料替換為反斜槓轉義序列。寫入時,可以使用'xmlcharrefreplace'
(替換為適當的 XML 字元引用)或'namereplace'
(替換為\N{...}
轉義序列)。任何其他已向codecs.register_error()
註冊的錯誤處理名稱也是有效的。newline 控制如何處理行尾。它可以是
None
,''
,'\n'
,'\r'
和'\r\n'
。它的工作方式如下:從流中讀取輸入時,如果 newline 為
None
,則啟用 通用換行符 模式。輸入中的行可以以'\n'
、'\r'
或'\r\n'
結尾,並且在返回給呼叫者之前,這些結尾會被轉換為'\n'
。如果 newline 為''
,則啟用通用換行符模式,但行尾將以未轉換的形式返回給呼叫者。如果 newline 具有任何其他合法值,則輸入行僅以給定的字串結尾,並且行尾將以未轉換的形式返回給呼叫者。向流中寫入輸出時,如果 newline 為
None
,則任何寫入的'\n'
字元都會被轉換為系統預設的行分隔符,即os.linesep
。如果 newline 為''
或'\n'
,則不會進行轉換。如果 newline 為任何其他合法值,則任何寫入的'\n'
字元都將轉換為給定的字串。
如果 line_buffering 為
True
,則當對 write 的呼叫包含換行符或回車符時,會隱式呼叫flush()
。如果 write_through 為
True
,則保證對write()
的呼叫不會被緩衝:在TextIOWrapper
物件上寫入的任何資料都會立即傳遞到其底層的二進位制 buffer。在 3.3 版本中更改: 添加了 write_through 引數。
在 3.3 版本中更改: 預設的 encoding 現在是
locale.getpreferredencoding(False)
而不是locale.getpreferredencoding()
。不要臨時使用locale.setlocale()
更改區域設定編碼,而是使用當前的區域設定編碼,而不是使用者首選的編碼。在 3.10 版本中更改: encoding 引數現在支援
"locale"
虛擬編碼名稱。TextIOWrapper
除了TextIOBase
和IOBase
中的屬性和方法外,還提供以下資料屬性和方法:- line_buffering¶
是否啟用了行緩衝。
- write_through¶
寫入是否立即傳遞到底層的二進位制緩衝區。
在 3.7 版本中新增。
- reconfigure(*, encoding=None, errors=None, newline=None, line_buffering=None, write_through=None)¶
使用 encoding、errors、newline、line_buffering 和 write_through 的新設定重新配置此文字流。
未指定的引數將保留當前設定,但當指定 encoding 但未指定 errors 時,將使用
errors='strict'
。如果已從流中讀取了一些資料,則無法更改編碼或換行符。另一方面,可以在寫入後更改編碼。
此方法在設定新引數之前會隱式重新整理流。
在 3.7 版本中新增。
在 3.11 版本中更改: 該方法支援
encoding="locale"
選項。
- class io.StringIO(initial_value='', newline='\n')¶
使用記憶體中文字緩衝區的文字流。它繼承自
TextIOBase
。當呼叫
close()
方法時,文字緩衝區將被丟棄。可以透過提供 *initial_value* 來設定緩衝區的初始值。如果啟用了換行符轉換,則換行符將按照
write()
的方式進行編碼。流位於緩衝區的開頭,模擬以w+
模式開啟現有檔案,使其可以從頭開始立即寫入或進行覆蓋初始值的寫入。要模擬以a+
模式開啟檔案以便追加,請使用f.seek(0, io.SEEK_END)
將流重新定位到緩衝區的末尾。*newline* 引數的工作方式類似於
TextIOWrapper
的引數,但當向流寫入輸出時,如果 *newline* 為None
,則在所有平臺上換行符都會寫入為\n
。StringIO
除了提供來自TextIOBase
和IOBase
的方法外,還提供了此方法用法示例
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¶
一個用於解碼 通用換行符 模式下的換行符的輔助編解碼器。它繼承自
codecs.IncrementalDecoder
。
效能¶
本節討論提供的具體 I/O 實現的效能。
二進位制 I/O¶
透過僅讀取和寫入大資料塊(即使在使用者請求單個位元組時),緩衝 I/O 隱藏了呼叫和執行作業系統無緩衝 I/O 例程的任何效率低下之處。增益取決於作業系統和執行的 I/O 型別。例如,在某些現代作業系統(如 Linux)上,無緩衝磁碟 I/O 可以與緩衝 I/O 一樣快。然而,最重要的是,緩衝 I/O 提供了可預測的效能,而與平臺和支援裝置無關。因此,對於二進位制資料,幾乎總是最好使用緩衝 I/O 而不是無緩衝 I/O。
文字 I/O¶
在二進位制儲存(如檔案)上進行文字 I/O 比在同一儲存上進行二進位制 I/O 要慢得多,因為它需要使用字元編解碼器在 Unicode 和二進位制資料之間進行轉換。這在處理大量文字資料(如大型日誌檔案)時會變得明顯。此外,由於所使用的重構演算法,tell()
和 seek()
都非常慢。
多執行緒¶
FileIO
物件是執行緒安全的,其程度取決於它們包裝的作業系統呼叫(例如 Unix 下的 read(2) )的執行緒安全性。
二進位制緩衝物件(BufferedReader
、BufferedWriter
、BufferedRandom
和 BufferedRWPair
的例項)使用鎖來保護其內部結構;因此,可以安全地從多個執行緒同時呼叫它們。
TextIOWrapper
物件不是執行緒安全的。
可重入性¶
二進位制緩衝物件(BufferedReader
、BufferedWriter
、BufferedRandom
和 BufferedRWPair
的例項)不是可重入的。雖然在正常情況下不會發生可重入呼叫,但它們可能會因在 signal
處理程式中執行 I/O 而產生。如果一個執行緒試圖重新進入它已經在訪問的緩衝物件,則會引發 RuntimeError
。請注意,這並不禁止不同的執行緒進入緩衝物件。
上述情況隱含地擴充套件到文字檔案,因為 open()
函式會在 TextIOWrapper
中包裝一個緩衝物件。這包括標準流,因此也會影響內建的 print()
函式。