codecs
— 編解碼器登錄檔和基類¶
原始碼: Lib/codecs.py
此模組為標準 Python 編解碼器(編碼器和解碼器)定義了基類,並提供了對內部 Python 編解碼器登錄檔的訪問,該登錄檔管理編解碼器和錯誤處理查詢過程。大多數標準編解碼器是文字編碼,它將文字編碼為位元組(並將位元組解碼為文字),但也提供了將文字編碼為文字以及將位元組編碼為位元組的編解碼器。自定義編解碼器可以在任意型別之間進行編碼和解碼,但某些模組功能僅限於與文字編碼或編碼為bytes
的編解碼器一起使用。
該模組定義了以下函式,用於使用任何編解碼器進行編碼和解碼
- codecs.encode(obj, encoding='utf-8', errors='strict')¶
使用為 *encoding* 註冊的編解碼器對 *obj* 進行編碼。
可以給定 *errors* 來設定所需的錯誤處理方案。預設錯誤處理程式是
'strict'
,這意味著編碼錯誤會引發ValueError
(或更具體的編解碼器子類,如UnicodeEncodeError
)。有關編解碼器錯誤處理的更多資訊,請參閱編解碼器基類。
- codecs.decode(obj, encoding='utf-8', errors='strict')¶
使用為 *encoding* 註冊的編解碼器對 *obj* 進行解碼。
可以給定 *errors* 來設定所需的錯誤處理方案。預設錯誤處理程式是
'strict'
,這意味著解碼錯誤會引發ValueError
(或更具體的編解碼器子類,如UnicodeDecodeError
)。有關編解碼器錯誤處理的更多資訊,請參閱編解碼器基類。
每個編解碼器的完整詳細資訊也可以直接查詢
- codecs.lookup(encoding)¶
在 Python 編解碼器登錄檔中查詢編解碼器資訊,並返回一個
CodecInfo
物件,如下所述。首先在登錄檔的快取中查詢編碼。如果未找到,則掃描已註冊的搜尋函式列表。如果未找到
CodecInfo
物件,則會引發LookupError
。否則,CodecInfo
物件將儲存在快取中並返回給呼叫者。
- class codecs.CodecInfo(encode, decode, streamreader=None, streamwriter=None, incrementalencoder=None, incrementaldecoder=None, name=None)¶
查詢編解碼器登錄檔時的編解碼器詳細資訊。建構函式引數儲存在同名屬性中
- name¶
編碼的名稱。
- encode¶
- decode¶
無狀態的編碼和解碼函式。這些必須是函式或方法,它們具有與 Codec 例項的
encode()
和decode()
方法相同的介面(請參閱編解碼器介面)。這些函式或方法應以無狀態模式工作。
- incrementalencoder¶
- incrementaldecoder¶
增量式編碼器和解碼器類或工廠函式。它們必須提供由基類
IncrementalEncoder
和IncrementalDecoder
定義的介面。增量式編解碼器可以保持狀態。
- streamwriter¶
- streamreader¶
流寫入器和讀取器類或工廠函式。 這些必須提供由基類
StreamWriter
和StreamReader
分別定義的介面。 流編解碼器可以維護狀態。
為了簡化對各種編解碼器元件的訪問,該模組提供了這些額外的函式,它們使用 lookup()
進行編解碼器查詢。
- codecs.getencoder(encoding)¶
查詢給定編碼的編解碼器,並返回其編碼器函式。
如果找不到編碼,則引發
LookupError
。
- codecs.getdecoder(encoding)¶
查詢給定編碼的編解碼器,並返回其解碼器函式。
如果找不到編碼,則引發
LookupError
。
- codecs.getincrementalencoder(encoding)¶
查詢給定編碼的編解碼器,並返回其增量編碼器類或工廠函式。
如果找不到編碼或編解碼器不支援增量編碼器,則引發
LookupError
。
- codecs.getincrementaldecoder(encoding)¶
查詢給定編碼的編解碼器,並返回其增量解碼器類或工廠函式。
如果找不到編碼或編解碼器不支援增量解碼器,則引發
LookupError
。
- codecs.getreader(encoding)¶
查詢給定編碼的編解碼器,並返回其
StreamReader
類或工廠函式。如果找不到編碼,則引發
LookupError
。
- codecs.getwriter(encoding)¶
查詢給定編碼的編解碼器,並返回其
StreamWriter
類或工廠函式。如果找不到編碼,則引發
LookupError
。
透過註冊合適的編解碼器搜尋函式,可以使用自定義編解碼器。
- codecs.register(search_function)¶
註冊一個編解碼器搜尋函式。 搜尋函式應接受一個引數,該引數是以全小寫字母表示的編碼名稱,並將連字元和空格轉換為下劃線,並返回一個
CodecInfo
物件。 如果搜尋函式找不到給定的編碼,則應返回None
。在 3.9 版本中變更:連字元和空格將轉換為下劃線。
- codecs.unregister(search_function)¶
取消註冊編解碼器搜尋函式並清除登錄檔的快取。 如果搜尋函式未註冊,則不執行任何操作。
在 3.10 版本中新增。
雖然內建的 open()
和相關的 io
模組是處理編碼文字檔案的推薦方法,但此模組提供了額外的實用函式和類,允許在使用二進位制檔案時使用更廣泛的編解碼器。
- codecs.open(filename, mode='r', encoding=None, errors='strict', buffering=-1)¶
使用給定的 mode 開啟一個編碼檔案,並返回
StreamReaderWriter
的例項,提供透明的編碼/解碼。 預設的檔案模式是'r'
,表示以讀取模式開啟檔案。注意
如果 encoding 不是
None
,則底層編碼檔案始終以二進位制模式開啟。 在讀取和寫入時,不會自動轉換'\n'
。 mode 引數可以是內建open()
函式接受的任何二進位制模式; 將自動新增'b'
。encoding 指定用於該檔案的編碼。 允許任何編碼為和解碼自位元組的編碼,並且檔案方法支援的資料型別取決於所使用的編解碼器。
可以給定 errors 來定義錯誤處理。 它預設為
'strict'
,這會導致在發生編碼錯誤時引發ValueError
。buffering 的含義與內建
open()
函式的含義相同。 它預設為 -1,這意味著將使用預設緩衝區大小。在 3.11 版本中變更:
'U'
模式已被刪除。
- codecs.EncodedFile(file, data_encoding, file_encoding=None, errors='strict')¶
返回
StreamRecoder
例項,它是 file 的包裝版本,提供透明的轉碼。 當關閉包裝版本時,將關閉原始檔案。根據給定的 data_encoding 對寫入包裝檔案的資料進行解碼,然後使用 file_encoding 以位元組形式寫入原始檔案。 從原始檔案讀取的位元組將根據 file_encoding 進行解碼,結果將使用 data_encoding 進行編碼。
如果未給出 file_encoding,則預設為 data_encoding。
可以給定 errors 來定義錯誤處理。 它預設為
'strict'
,這會導致在發生編碼錯誤時引發ValueError
。
- codecs.iterencode(iterator, encoding, errors='strict', **kwargs)¶
使用增量編碼器迭代編碼由iterator提供的輸入。此函式是一個生成器。errors引數(以及任何其他關鍵字引數)將傳遞給增量編碼器。
此函式要求編解碼器接受文字
str
物件進行編碼。因此,它不支援位元組到位元組的編碼器,例如base64_codec
。
- codecs.iterdecode(iterator, encoding, errors='strict', **kwargs)¶
使用增量解碼器迭代解碼由iterator提供的輸入。此函式是一個生成器。errors引數(以及任何其他關鍵字引數)將傳遞給增量解碼器。
此函式要求編解碼器接受
bytes
物件進行解碼。因此,它不支援文字到文字的編碼器,例如rot_13
,儘管rot_13
可以與iterencode()
等效使用。
該模組還提供了以下常量,這些常量對於讀取和寫入平臺相關的檔案非常有用
- codecs.BOM¶
- codecs.BOM_BE¶
- codecs.BOM_LE¶
- codecs.BOM_UTF8¶
- codecs.BOM_UTF16¶
- codecs.BOM_UTF16_BE¶
- codecs.BOM_UTF16_LE¶
- codecs.BOM_UTF32¶
- codecs.BOM_UTF32_BE¶
- codecs.BOM_UTF32_LE¶
這些常量定義了各種位元組序列,即幾種編碼的 Unicode 位元組順序標記(BOM)。它們在 UTF-16 和 UTF-32 資料流中用於指示使用的位元組順序,並在 UTF-8 中用作 Unicode 簽名。
BOM_UTF16
是BOM_UTF16_BE
或BOM_UTF16_LE
,具體取決於平臺的本機位元組順序,BOM
是BOM_UTF16
的別名,BOM_LE
是BOM_UTF16_LE
的別名,BOM_BE
是BOM_UTF16_BE
的別名。其他常量表示 UTF-8 和 UTF-32 編碼中的 BOM。
編解碼器基類¶
codecs
模組定義了一組基類,這些基類定義了使用編解碼器物件的介面,也可以用作自定義編解碼器實現的基礎。
每個編解碼器都必須定義四個介面,才能在 Python 中用作編解碼器:無狀態編碼器、無狀態解碼器、流讀取器和流寫入器。流讀取器和寫入器通常重用無狀態編碼器/解碼器來實現檔案協議。編解碼器作者還需要定義編解碼器如何處理編碼和解碼錯誤。
錯誤處理程式¶
為了簡化和標準化錯誤處理,編解碼器可以透過接受 errors 字串引數來實現不同的錯誤處理方案
>>> 'German ß, ♬'.encode(encoding='ascii', errors='backslashreplace')
b'German \\xdf, \\u266c'
>>> 'German ß, ♬'.encode(encoding='ascii', errors='xmlcharrefreplace')
b'German ß, ♬'
以下錯誤處理程式可用於所有 Python 標準編碼編解碼器
值 |
含義 |
---|---|
|
引發 |
|
忽略格式錯誤的資料,並繼續而不另行通知。在 |
|
替換為替換標記。在編碼時,使用 |
|
替換為反斜槓轉義序列。在編碼時,使用格式為 |
|
在解碼時,用介於 |
以下錯誤處理程式僅適用於編碼(在文字編碼中)
值 |
含義 |
---|---|
|
替換為 XML/HTML 數字字元引用,它是格式為 |
|
替換為 |
此外,以下錯誤處理程式特定於給定的編解碼器
值 |
編解碼器 |
含義 |
---|---|---|
|
utf-8、utf-16、utf-32、utf-16-be、utf-16-le、utf-32-be、utf-32-le |
允許將代理程式碼點( |
3.1 版本新增: 'surrogateescape'
和 'surrogatepass'
錯誤處理控制代碼。
3.4 版本更改: 'surrogatepass'
錯誤處理控制代碼現在可以與 utf-16* 和 utf-32* 編解碼器一起使用。
3.5 版本新增: 'namereplace'
錯誤處理控制代碼。
3.5 版本更改: 'backslashreplace'
錯誤處理控制代碼現在可以用於解碼和轉換。
允許的值的集合可以透過註冊新的命名錯誤處理控制代碼來擴充套件
- codecs.register_error(name, error_handler)¶
以 *name* 為名稱註冊錯誤處理函式 *error_handler*。 當 *name* 被指定為 errors 引數時,在編碼和解碼過程中發生錯誤時將呼叫 *error_handler* 引數。
對於編碼,*error_handler* 將被呼叫並傳遞一個
UnicodeEncodeError
例項,其中包含關於錯誤位置的資訊。 錯誤處理控制代碼必須引發此異常或其他異常,或者返回一個元組,其中包含輸入中無法編碼部分的替換以及編碼應繼續的位置。 替換可以是str
或bytes
。 如果替換是位元組,則編碼器將直接將其複製到輸出緩衝區。 如果替換是字串,則編碼器將對替換進行編碼。 編碼將從指定位置的原始輸入繼續進行。 負位置值將被視為相對於輸入字串的末尾。 如果結果位置超出範圍,則會引發IndexError
。解碼和轉換的工作方式類似,只是
UnicodeDecodeError
或UnicodeTranslateError
將被傳遞給處理控制代碼,並且來自錯誤處理控制代碼的替換將直接放入輸出中。
以前註冊的錯誤處理控制代碼(包括標準錯誤處理控制代碼)可以透過名稱查詢
- codecs.lookup_error(name)¶
返回先前以名稱 *name* 註冊的錯誤處理程式。
如果找不到處理控制代碼,則引發
LookupError
。
以下標準錯誤處理程式也可以作為模組級函式使用
- codecs.strict_errors(exception)¶
實現
'strict'
錯誤處理。每個編碼或解碼錯誤都會引發
UnicodeError
。
- codecs.ignore_errors(exception)¶
實現
'ignore'
錯誤處理。將忽略格式錯誤的資料;編碼或解碼將繼續進行,不再另行通知。
- codecs.replace_errors(exception)¶
實現
'replace'
錯誤處理。對於編碼錯誤,替換為
?
(ASCII 字元),對於解碼錯誤,替換為�
(U+FFFD,官方的替換字元)。
- codecs.backslashreplace_errors(exception)¶
實現
'backslashreplace'
錯誤處理。格式錯誤的資料將替換為反斜槓轉義序列。 在編碼時,使用格式為
\xhh
\uxxxx
\Uxxxxxxxx
的 Unicode 程式碼點的十六進位制形式。 在解碼時,使用格式為\xhh
的位元組值的十六進位制形式。3.5 版本更改: 可以用於解碼和轉換。
無狀態編碼和解碼¶
基本 Codec
類定義了這些方法,這些方法也定義了無狀態編碼器和解碼器的函式介面
- class codecs.Codec¶
- encode(input, errors='strict')¶
編碼物件 *input* 並返回一個元組(輸出物件,消耗的長度)。 例如,文字編碼 使用特定的字元集編碼(例如,
cp1252
或iso-8859-1
)將字串物件轉換為位元組物件。*errors* 引數定義要應用的錯誤處理。 它預設為
'strict'
處理。該方法可能不會在
Codec
例項中儲存狀態。 對於必須保持狀態才能使編碼高效的編解碼器,請使用StreamWriter
。編碼器必須能夠處理零長度輸入,並在這種情況下返回輸出物件型別的空物件。
- decode(input, errors='strict')¶
解碼物件 *input* 並返回一個元組(輸出物件,消耗的長度)。 例如,對於 文字編碼,解碼會將使用特定字元集編碼編碼的位元組物件轉換為字串物件。
對於文字編碼和位元組到位元組的編解碼器,*input* 必須是一個位元組物件,或提供只讀緩衝區介面的物件,例如緩衝區物件和記憶體對映檔案。
*errors* 引數定義要應用的錯誤處理。 它預設為
'strict'
處理。該方法可能不會在
Codec
例項中儲存狀態。 對於必須保持狀態才能使解碼高效的編解碼器,請使用StreamReader
。解碼器必須能夠處理零長度輸入,並在這種情況下返回輸出物件型別的空物件。
增量編碼和解碼¶
IncrementalEncoder
和 IncrementalDecoder
類為增量編碼和解碼提供了基本介面。編碼/解碼輸入不是透過一次呼叫無狀態的編碼器/解碼器函式完成,而是透過多次呼叫增量編碼器/解碼器的 encode()
/decode()
方法完成。增量編碼器/解碼器在方法呼叫期間會跟蹤編碼/解碼過程。
多次呼叫 encode()
/decode()
方法的輸出連線在一起,與將所有單個輸入連線成一個,然後使用無狀態的編碼器/解碼器進行編碼/解碼的結果相同。
IncrementalEncoder 物件¶
IncrementalEncoder
類用於分步驟編碼輸入。它定義了以下方法,每個增量編碼器都必須定義這些方法才能與 Python 編解碼器登錄檔相容。
- class codecs.IncrementalEncoder(errors='strict')¶
IncrementalEncoder
例項的建構函式。所有增量編碼器都必須提供此建構函式介面。它們可以自由新增額外的關鍵字引數,但只有此處定義的引數會被 Python 編解碼器登錄檔使用。
IncrementalEncoder
可以透過提供 *errors* 關鍵字引數來實現不同的錯誤處理方案。有關可能的值,請參閱 錯誤處理程式。*errors* 引數將被賦值給同名的屬性。透過賦值給此屬性,可以在
IncrementalEncoder
物件的生命週期內切換不同的錯誤處理策略。- encode(object, final=False)¶
編碼 *object*(考慮到編碼器的當前狀態)並返回編碼後的物件。如果這是最後一次呼叫
encode()
,則 *final* 必須為 true(預設值為 false)。
- reset()¶
將編碼器重置為初始狀態。輸出將被丟棄:如果需要,呼叫
.encode(object, final=True)
,傳遞一個空位元組或文字字串來重置編碼器並獲取輸出。
- getstate()¶
返回編碼器的當前狀態,該狀態必須為整數。實現應確保
0
是最常見的狀態。(比整數更復雜的狀態可以透過編組/pickle 該狀態,並將結果字串的位元組編碼為一個整數來轉換為整數。)
- setstate(state)¶
將編碼器的狀態設定為 *state*。*state* 必須是
getstate()
返回的編碼器狀態。
IncrementalDecoder 物件¶
IncrementalDecoder
類用於分步驟解碼輸入。它定義了以下方法,每個增量解碼器都必須定義這些方法才能與 Python 編解碼器登錄檔相容。
- class codecs.IncrementalDecoder(errors='strict')¶
IncrementalDecoder
例項的建構函式。所有增量解碼器都必須提供此建構函式介面。它們可以自由新增額外的關鍵字引數,但只有此處定義的引數會被 Python 編解碼器登錄檔使用。
IncrementalDecoder
可以透過提供 *errors* 關鍵字引數來實現不同的錯誤處理方案。有關可能的值,請參閱 錯誤處理程式。*errors* 引數將被賦值給同名的屬性。透過賦值給此屬性,可以在
IncrementalDecoder
物件的生命週期內切換不同的錯誤處理策略。- decode(object, final=False)¶
解碼 *object*(考慮到解碼器的當前狀態)並返回解碼後的物件。如果這是最後一次呼叫
decode()
,則 *final* 必須為 true(預設值為 false)。如果 *final* 為 true,則解碼器必須完全解碼輸入並重新整理所有緩衝區。如果無法做到這一點(例如,因為輸入結尾處存在不完整的位元組序列),則必須像無狀態情況一樣啟動錯誤處理(這可能會引發異常)。
- reset()¶
將解碼器重置為初始狀態。
- getstate()¶
返回解碼器的當前狀態。這必須是一個包含兩個項的元組,第一項必須是包含尚未解碼的輸入的緩衝區。第二項必須是一個整數,並且可以是附加狀態資訊。(實現應確保
0
是最常見的附加狀態資訊。)如果此附加狀態資訊為0
,則必須可以將解碼器設定為沒有緩衝輸入且附加狀態資訊為0
的狀態,以便將先前緩衝的輸入饋送到解碼器可以使其返回到之前的狀態,而不會產生任何輸出。(比整數更復雜的附加狀態資訊可以透過編組/pickle 該資訊,並將結果字串的位元組編碼為一個整數來轉換為整數。)
- setstate(state)¶
將解碼器的狀態設定為 *state*。*state* 必須是
getstate()
返回的解碼器狀態。
流編碼和解碼¶
StreamWriter
和 StreamReader
類提供了通用的工作介面,可以非常容易地使用這些介面來實現新的編碼子模組。有關如何執行此操作的示例,請參閱 encodings.utf_8
。
StreamWriter 物件¶
StreamWriter
類是 Codec
的子類,並定義了以下方法,每個流寫入器都必須定義這些方法才能與 Python 編解碼器登錄檔相容。
- class codecs.StreamWriter(stream, errors='strict')¶
StreamWriter
例項的建構函式。所有流寫入器都必須提供此建構函式介面。它們可以自由新增額外的關鍵字引數,但只有此處定義的引數會被 Python 編解碼器登錄檔使用。
*stream* 引數必須是一個類似於檔案的物件,該物件開啟用於寫入文字或二進位制資料,具體取決於特定的編解碼器。
StreamWriter
可以透過提供 *errors* 關鍵字引數來實現不同的錯誤處理方案。有關底層流編解碼器可能支援的標準錯誤處理程式,請參閱 錯誤處理程式。errors 引數將被賦值給同名的屬性。賦值給此屬性可以在
StreamWriter
物件的生命週期內切換不同的錯誤處理策略。- write(object)¶
將物件的內容編碼後寫入流。
- reset()¶
重置用於保持內部狀態的編解碼器緩衝區。
呼叫此方法應確保輸出上的資料處於乾淨狀態,允許附加新的新鮮資料,而無需重新掃描整個流來恢復狀態。
除了上述方法外,StreamWriter
還必須繼承底層流的所有其他方法和屬性。
StreamReader 物件¶
StreamReader
類是 Codec
的子類,並定義了每個流讀取器為了與 Python 編解碼器登錄檔相容而必須定義的以下方法。
- class codecs.StreamReader(stream, errors='strict')¶
StreamReader
例項的建構函式。所有流讀取器都必須提供此建構函式介面。它們可以自由新增額外的關鍵字引數,但只有此處定義的引數才會被 Python 編解碼器登錄檔使用。
stream 引數必須是一個類似於檔案的物件,開啟用於讀取文字或二進位制資料,具體取決於特定的編解碼器。
StreamReader
可以透過提供 errors 關鍵字引數來實現不同的錯誤處理方案。有關底層流編解碼器可能支援的標準錯誤處理程式,請參見 錯誤處理程式。errors 引數將被賦值給同名的屬性。賦值給此屬性可以在
StreamReader
物件的生命週期內切換不同的錯誤處理策略。可以使用
register_error()
擴充套件 errors 引數允許的值的集合。- read(size=-1, chars=-1, firstline=False)¶
解碼流中的資料並返回結果物件。
chars 引數指示要返回的已解碼程式碼點或位元組數。
read()
方法永遠不會返回超過請求的資料,但如果可用資料不足,它可能會返回較少的資料。size 引數指示要讀取進行解碼的編碼位元組或程式碼點的近似最大數量。解碼器可以根據需要修改此設定。預設值 -1 表示讀取和解碼儘可能多的資料。此引數旨在防止必須一步解碼大型檔案。
firstline 標誌表示如果後面的行出現解碼錯誤,則僅返回第一行就足夠了。
該方法應使用貪婪讀取策略,這意味著它應讀取在編碼定義和給定大小內允許的最大資料量,例如,如果流上提供了可選的編碼結尾或狀態標記,則也應讀取這些資料。
- readline(size=None, keepends=True)¶
從輸入流讀取一行並返回解碼後的資料。
如果給定 size,則將其作為大小引數傳遞給流的
read()
方法。如果 keepends 為 false,則將從返回的行中刪除行尾。
- readlines(sizehint=None, keepends=True)¶
讀取輸入流上所有可用的行,並將它們作為行列表返回。
行尾是使用編解碼器的
decode()
方法實現的,如果 keepends 為 true,則包含在列表條目中。如果給定 sizehint,則將其作為 size 引數傳遞給流的
read()
方法。
- reset()¶
重置用於保持內部狀態的編解碼器緩衝區。
請注意,不應發生流重新定位。此方法的主要目的是能夠從解碼錯誤中恢復。
除了上述方法外,StreamReader
還必須繼承底層流的所有其他方法和屬性。
StreamReaderWriter 物件¶
StreamReaderWriter
是一個方便的類,允許包裝在讀取和寫入模式下工作的流。
其設計方式使得可以使用 lookup()
函式返回的工廠函式來構造例項。
- class codecs.StreamReaderWriter(stream, Reader, Writer, errors='strict')¶
建立
StreamReaderWriter
例項。stream 必須是類似於檔案的物件。Reader 和 Writer 必須是提供StreamReader
和StreamWriter
介面的工廠函式或類。錯誤處理的方式與流讀取器和寫入器的定義方式相同。
StreamReaderWriter
例項定義了 StreamReader
和 StreamWriter
類的組合介面。它們繼承底層流的所有其他方法和屬性。
StreamRecoder 物件¶
StreamRecoder
將資料從一種編碼轉換為另一種編碼,這在處理不同的編碼環境時有時很有用。
其設計方式使得可以使用 lookup()
函式返回的工廠函式來構造例項。
- class codecs.StreamRecoder(stream, encode, decode, Reader, Writer, errors='strict')¶
建立一個
StreamRecoder
例項,該例項實現雙向轉換:encode 和 decode 在前端工作 — 對呼叫read()
和write()
的程式碼可見的資料進行操作,而 Reader 和 Writer 在後端工作 — 對 stream 中的資料進行操作。您可以使用這些物件進行透明的轉碼,例如從 Latin-1 到 UTF-8 並返回。
stream 引數必須是類檔案物件。
encode 和 decode 引數必須符合
Codec
介面。Reader 和 Writer 必須是工廠函式或類,分別提供StreamReader
和StreamWriter
介面的物件。錯誤處理的方式與為流讀取器和寫入器定義的方式相同。
StreamRecoder
例項定義了 StreamReader
和 StreamWriter
類的組合介面。它們從底層流繼承所有其他方法和屬性。
編碼和 Unicode¶
字串在內部儲存為程式碼點序列,範圍為 U+0000
–U+10FFFF
。(有關實現的更多詳細資訊,請參閱 PEP 393。)一旦字串物件在 CPU 和記憶體之外使用,位元組序以及這些陣列如何儲存為位元組就成為問題。與其他編解碼器一樣,將字串序列化為位元組序列稱為編碼,而從位元組序列重建字串稱為解碼。有各種不同的文字序列化編解碼器,它們統稱為文字編碼。
最簡單的文字編碼(稱為 'latin-1'
或 'iso-8859-1'
)將程式碼點 0–255 對映到位元組 0x0
–0xff
,這意味著包含高於 U+00FF
的程式碼點的字串物件無法使用此編解碼器進行編碼。這樣做會引發 UnicodeEncodeError
,如下所示(儘管錯誤訊息的詳細資訊可能有所不同): UnicodeEncodeError: 'latin-1' codec can't encode character '\u1234' in position 3: ordinal not in range(256)
。
還有另一組編碼(所謂的字元對映編碼)選擇所有 Unicode 程式碼點的不同子集,以及這些程式碼點如何對映到位元組 0x0
–0xff
。要了解如何做到這一點,只需開啟例如 encodings/cp1252.py
(它主要在 Windows 上使用的一種編碼)。有一個包含 256 個字元的字串常量,它顯示哪個字元對映到哪個位元組值。
所有這些編碼只能編碼 Unicode 中定義的 1114112 個程式碼點中的 256 個。一種可以儲存每個 Unicode 程式碼點的簡單直接的方法是將每個程式碼點儲存為四個連續的位元組。有兩種可能性:以大端或小端順序儲存位元組。這兩種編碼分別稱為 UTF-32-BE
和 UTF-32-LE
。它們的缺點是,例如,如果在小端機器上使用 UTF-32-BE
,則始終需要在編碼和解碼時交換位元組。UTF-32
避免了這個問題:位元組始終處於自然位元組序。當具有不同位元組序的 CPU 讀取這些位元組時,必須交換位元組。為了能夠檢測 UTF-16
或 UTF-32
位元組序列的位元組序,有所謂的 BOM(“位元組順序標記”)。這是 Unicode 字元 U+FEFF
。此字元可以新增到每個 UTF-16
或 UTF-32
位元組序列。此字元的位元組交換版本 (0xFFFE
) 是一個非法字元,不得出現在 Unicode 文字中。因此,當 UTF-16
或 UTF-32
位元組序列中的第一個字元看起來像是 U+FFFE
時,必須在解碼時交換位元組。不幸的是,字元 U+FEFF
還有第二個用途,作為 零寬度不換行空格
:一個沒有寬度且不允許拆分單詞的字元。例如,它可用於為連字演算法提供提示。在 Unicode 4.0 中,使用 U+FEFF
作為 零寬度不換行空格
已被棄用(U+2060
(單詞連線符
)承擔此角色)。儘管如此,Unicode 軟體仍然必須能夠處理 U+FEFF
的兩種角色:作為 BOM,它是確定編碼位元組的儲存佈局的裝置,並在位元組序列解碼為字串後消失;作為 零寬度不換行空格
,它是一個普通字元,將像任何其他字元一樣解碼。
還有另一種編碼能夠對全範圍的 Unicode 字元進行編碼:UTF-8。UTF-8 是一種 8 位編碼,這意味著 UTF-8 中不存在位元組順序問題。UTF-8 位元組序列中的每個位元組都由兩部分組成:標記位(最高有效位)和有效負載位。標記位是零到四個 1
位後跟一個 0
位的序列。Unicode 字元的編碼方式如下(其中 x 是有效負載位,當連線時給出 Unicode 字元)
範圍 |
編碼 |
---|---|
|
0xxxxxxx |
|
110xxxxx 10xxxxxx |
|
1110xxxx 10xxxxxx 10xxxxxx |
|
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
Unicode 字元的最低有效位是最右邊的 x 位。
由於 UTF-8 是 8 位編碼,因此不需要 BOM,並且解碼字串中的任何 U+FEFF
字元(即使它是第一個字元)都被視為 零寬度不換行空格
。
在沒有外部資訊的情況下,不可能可靠地確定用於編碼字串的編碼。每個字元對映編碼都可以解碼任何隨機位元組序列。但是,UTF-8 並非如此,因為 UTF-8 位元組序列具有不允許任意位元組序列的結構。為了提高 UTF-8 編碼的檢測可靠性,Microsoft 為其記事本程式發明了 UTF-8 的一種變體(Python 稱之為 "utf-8-sig"
):在任何 Unicode 字元寫入檔案之前,寫入 UTF-8 編碼的 BOM(作為位元組序列如下所示:0xef
、0xbb
、0xbf
)。由於任何字元對映編碼檔案都不太可能以這些位元組值開頭(例如,這將對映到
帶分音符的拉丁小寫字母 I右指雙角引號倒問號
在 iso-8859-1 中),這增加了從位元組序列中正確猜測 utf-8-sig
編碼的可能性。因此,這裡的 BOM 不是用來確定生成位元組序列所使用的位元組順序,而是作為一種有助於猜測編碼的簽名。在編碼時,utf-8-sig 編解碼器會將 0xef
、0xbb
、0xbf
作為前三個位元組寫入檔案。在解碼時,如果 utf-8-sig
發現這三個位元組出現在檔案的開頭,它會跳過這三個位元組。在 UTF-8 中,不鼓勵使用 BOM,通常應避免使用。
標準編碼¶
Python 內建了許多編解碼器,它們要麼以 C 函式實現,要麼使用字典作為對映表。下表按名稱列出了編解碼器,以及一些常見的別名和編碼可能使用的語言。別名列表和語言列表均未詳盡列出。請注意,僅大小寫或使用連字元而不是下劃線而不同的拼寫變體也是有效的別名;因此,例如 'utf-8'
是 'utf_8'
編解碼器的有效別名。
CPython 實現細節: 一些常見的編碼可以繞過編解碼器查詢機制以提高效能。這些最佳化機會僅由 CPython 識別,並且僅限於一組(不區分大小寫)的別名:utf-8、utf8、latin-1、latin1、iso-8859-1、iso8859-1、mbcs(僅限 Windows)、ascii、us-ascii、utf-16、utf16、utf-32、utf32,以及使用下劃線代替破折號的版本。對這些編碼使用其他別名可能會導致執行速度變慢。
在 3.6 版本中更改:為 us-ascii 識別最佳化機會。
許多字元集支援相同的語言。它們在單個字元(例如,是否支援歐元符號)以及字元到程式碼位置的分配方面有所不同。特別是對於歐洲語言,通常存在以下變體:
ISO 8859 程式碼集
Microsoft Windows 內碼表,它通常是從 8859 程式碼集派生的,但將控制字元替換為額外的圖形字元
IBM EBCDIC 內碼表
IBM PC 內碼表,它與 ASCII 相容
Codec |
別名 |
語言 |
---|---|---|
ascii |
646, us-ascii |
英語 |
big5 |
big5-tw, csbig5 |
繁體中文 |
big5hkscs |
big5-hkscs, hkscs |
繁體中文 |
cp037 |
IBM037, IBM039 |
英語 |
cp273 |
273, IBM273, csIBM273 |
德語 在 3.4 版本中新增。 |
cp424 |
EBCDIC-CP-HE, IBM424 |
希伯來語 |
cp437 |
437, IBM437 |
英語 |
cp500 |
EBCDIC-CP-BE, EBCDIC-CP-CH, IBM500 |
西歐 |
cp720 |
阿拉伯語 |
|
cp737 |
希臘語 |
|
cp775 |
IBM775 |
波羅的海語 |
cp850 |
850, IBM850 |
西歐 |
cp852 |
852, IBM852 |
中歐和東歐 |
cp855 |
855, IBM855 |
保加利亞語、白俄羅斯語、馬其頓語、俄語、塞爾維亞語 |
cp856 |
希伯來語 |
|
cp857 |
857, IBM857 |
土耳其語 |
cp858 |
858, IBM858 |
西歐 |
cp860 |
860, IBM860 |
葡萄牙語 |
cp861 |
861, CP-IS, IBM861 |
冰島語 |
cp862 |
862, IBM862 |
希伯來語 |
cp863 |
863, IBM863 |
加拿大 |
cp864 |
IBM864 |
阿拉伯語 |
cp865 |
865, IBM865 |
丹麥語、挪威語 |
cp866 |
866, IBM866 |
俄語 |
cp869 |
869, CP-GR, IBM869 |
希臘語 |
cp874 |
泰語 |
|
cp875 |
希臘語 |
|
cp932 |
932, ms932, mskanji, ms-kanji, windows-31j |
日語 |
cp949 |
949, ms949, uhc |
韓語 |
cp950 |
950, ms950 |
繁體中文 |
cp1006 |
烏爾都語 |
|
cp1026 |
ibm1026 |
土耳其語 |
cp1125 |
1125, ibm1125, cp866u, ruscii |
烏克蘭語 在 3.4 版本中新增。 |
cp1140 |
ibm1140 |
西歐 |
cp1250 |
windows-1250 |
中歐和東歐 |
cp1251 |
windows-1251 |
保加利亞語、白俄羅斯語、馬其頓語、俄語、塞爾維亞語 |
cp1252 |
windows-1252 |
西歐 |
cp1253 |
windows-1253 |
希臘語 |
cp1254 |
windows-1254 |
土耳其語 |
cp1255 |
windows-1255 |
希伯來語 |
cp1256 |
windows-1256 |
阿拉伯語 |
cp1257 |
windows-1257 |
波羅的海語 |
cp1258 |
windows-1258 |
越南語 |
euc_jp |
eucjp, ujis, u-jis |
日語 |
euc_jis_2004 |
jisx0213, eucjis2004 |
日語 |
euc_jisx0213 |
eucjisx0213 |
日語 |
euc_kr |
euckr, korean, ksc5601, ks_c-5601, ks_c-5601-1987, ksx1001, ks_x-1001 |
韓語 |
gb2312 |
chinese, csiso58gb231280, euc-cn, euccn, eucgb2312-cn, gb2312-1980, gb2312-80, iso-ir-58 |
簡體中文 |
gbk |
936, cp936, ms936 |
統一漢字 |
gb18030 |
gb18030-2000 |
統一漢字 |
hz |
hzgb, hz-gb, hz-gb-2312 |
簡體中文 |
iso2022_jp |
csiso2022jp, iso2022jp, iso-2022-jp |
日語 |
iso2022_jp_1 |
iso2022jp-1, iso-2022-jp-1 |
日語 |
iso2022_jp_2 |
iso2022jp-2, iso-2022-jp-2 |
日語、韓語、簡體中文、西歐、希臘語 |
iso2022_jp_2004 |
iso2022jp-2004, iso-2022-jp-2004 |
日語 |
iso2022_jp_3 |
iso2022jp-3, iso-2022-jp-3 |
日語 |
iso2022_jp_ext |
iso2022jp-ext, iso-2022-jp-ext |
日語 |
iso2022_kr |
csiso2022kr, iso2022kr, iso-2022-kr |
韓語 |
latin_1 |
iso-8859-1, iso8859-1, 8859, cp819, latin, latin1, L1 |
西歐 |
iso8859_2 |
iso-8859-2, latin2, L2 |
中歐和東歐 |
iso8859_3 |
iso-8859-3, latin3, L3 |
世界語、馬耳他語 |
iso8859_4 |
iso-8859-4, latin4, L4 |
波羅的海語 |
iso8859_5 |
iso-8859-5, 西里爾語 |
保加利亞語、白俄羅斯語、馬其頓語、俄語、塞爾維亞語 |
iso8859_6 |
iso-8859-6, 阿拉伯語 |
阿拉伯語 |
iso8859_7 |
iso-8859-7, 希臘語, greek8 |
希臘語 |
iso8859_8 |
iso-8859-8, 希伯來語 |
希伯來語 |
iso8859_9 |
iso-8859-9, latin5, L5 |
土耳其語 |
iso8859_10 |
iso-8859-10, latin6, L6 |
北歐語言 |
iso8859_11 |
iso-8859-11, 泰語 |
泰語 |
iso8859_13 |
iso-8859-13, latin7, L7 |
波羅的海語 |
iso8859_14 |
iso-8859-14, latin8, L8 |
凱爾特語 |
iso8859_15 |
iso-8859-15, latin9, L9 |
西歐 |
iso8859_16 |
iso-8859-16, latin10, L10 |
東南歐 |
johab |
cp1361, ms1361 |
韓語 |
koi8_r |
俄語 |
|
koi8_t |
塔吉克語 3.5 版本新增。 |
|
koi8_u |
烏克蘭語 |
|
kz1048 |
kz_1048, strk1048_2002, rk1048 |
哈薩克語 3.5 版本新增。 |
mac_cyrillic |
maccyrillic |
保加利亞語、白俄羅斯語、馬其頓語、俄語、塞爾維亞語 |
mac_greek |
macgreek |
希臘語 |
mac_iceland |
maciceland |
冰島語 |
mac_latin2 |
maclatin2, maccentraleurope, mac_centeuro |
中歐和東歐 |
mac_roman |
macroman, macintosh |
西歐 |
mac_turkish |
macturkish |
土耳其語 |
ptcp154 |
csptcp154, pt154, cp154, cyrillic-asian |
哈薩克語 |
shift_jis |
csshiftjis, shiftjis, sjis, s_jis |
日語 |
shift_jis_2004 |
shiftjis2004, sjis_2004, sjis2004 |
日語 |
shift_jisx0213 |
shiftjisx0213, sjisx0213, s_jisx0213 |
日語 |
utf_32 |
U32, utf32 |
所有語言 |
utf_32_be |
UTF-32BE |
所有語言 |
utf_32_le |
UTF-32LE |
所有語言 |
utf_16 |
U16, utf16 |
所有語言 |
utf_16_be |
UTF-16BE |
所有語言 |
utf_16_le |
UTF-16LE |
所有語言 |
utf_7 |
U7, unicode-1-1-utf-7 |
所有語言 |
utf_8 |
U8, UTF, utf8, cp65001 |
所有語言 |
utf_8_sig |
所有語言 |
在 3.4 版本中更改:utf-16* 和 utf-32* 編碼器不再允許編碼代理程式碼點(U+D800
–U+DFFF
)。utf-32* 解碼器不再解碼對應於代理程式碼點的位元組序列。
在 3.8 版本中更改:cp65001
現在是 utf_8
的別名。
Python 特定編碼¶
許多預定義的編解碼器是 Python 特有的,因此它們的編解碼器名稱在 Python 之外沒有意義。它們在下表中根據預期的輸入和輸出型別列出(請注意,雖然文字編碼是編解碼器最常見的用例,但底層編解碼器基礎結構支援任意資料轉換,而不僅僅是文字編碼)。對於不對稱編解碼器,所述含義描述了編碼方向。
文字編碼¶
以下編解碼器提供 str
到 bytes
編碼和 類似位元組物件 到 str
解碼,類似於 Unicode 文字編碼。
Codec |
別名 |
含義 |
---|---|---|
idna |
實現 RFC 3490,另請參閱 |
|
mbcs |
ansi, dbcs |
僅限 Windows:根據 ANSI 內碼表 (CP_ACP) 對運算元進行編碼。 |
oem |
僅限 Windows:根據 OEM 內碼表 (CP_OEMCP) 對運算元進行編碼。 在 3.6 版本中新增。 |
|
palmos |
PalmOS 3.5 的編碼。 |
|
punycode |
實現 RFC 3492。不支援有狀態編解碼器。 |
|
raw_unicode_escape |
Latin-1 編碼,其他程式碼點使用 |
|
undefined |
為所有轉換引發異常,即使是空字串。錯誤處理程式將被忽略。 |
|
unicode_escape |
適合作為 ASCII 編碼的 Python 原始碼中 Unicode 字面量內容的編碼,只是引號不會被轉義。從 Latin-1 原始碼解碼。請注意,Python 原始碼實際上預設使用 UTF-8。 |
在 3.8 版本中更改:刪除了“unicode_internal”編解碼器。
二進位制轉換¶
以下編解碼器提供二進位制轉換:類位元組物件 到 bytes
的對映。它們不受 bytes.decode()
的支援(它只產生 str
輸出)。
Codec |
別名 |
含義 |
編碼器/解碼器 |
---|---|---|---|
base64_codec [1] |
base64, base_64 |
將運算元轉換為多行 MIME base64 格式(結果始終包含尾部的 在 3.4 版本中更改: 接受任何 類位元組物件 作為編碼和解碼的輸入。 |
|
bz2_codec |
bz2 |
使用 bz2 壓縮運算元。 |
|
hex_codec |
hex |
將運算元轉換為十六進位制表示,每個位元組使用兩位數字。 |
|
quopri_codec |
quopri, quotedprintable, quoted_printable |
將運算元轉換為 MIME quoted printable 格式。 |
|
uu_codec |
uu |
使用 uuencode 轉換運算元。 |
|
zlib_codec |
zip, zlib |
使用 gzip 壓縮運算元。 |
在 3.2 版本中加入: 恢復了二進位制轉換。
在 3.4 版本中更改: 恢復了二進位制轉換的別名。
文字轉換¶
以下編解碼器提供文字轉換:str
到 str
的對映。它不受 str.encode()
的支援(它只產生 bytes
輸出)。
Codec |
別名 |
含義 |
---|---|---|
rot_13 |
rot13 |
返回運算元的凱撒密碼加密結果。 |
在 3.2 版本中加入: 恢復了 rot_13
文字轉換。
在 3.4 版本中更改: 恢復了 rot13
別名。
encodings.idna
— 應用程式中的國際化域名¶
該模組實現了 RFC 3490(應用程式中的國際化域名)和 RFC 3492(Nameprep:國際化域名 (IDN) 的 Stringprep 配置檔案)。它基於 punycode
編碼和 stringprep
構建。
如果您需要 RFC 5891 和 RFC 5895 中的 IDNA 2008 標準,請使用第三方 idna 模組。
這些 RFC 共同定義了一個協議,以支援域名中的非 ASCII 字元。包含非 ASCII 字元的域名(例如 www.Alliancefrançaise.nu
)會被轉換為 ASCII 相容編碼 (ACE),例如 www.xn--alliancefranaise-npb.nu
。域名 ACE 形式隨後被用於協議不允許使用任意字元的所有位置,例如 DNS 查詢、HTTP Host 欄位等等。此轉換在應用程式中進行,如果可能,則對使用者不可見:應用程式應該在網路傳輸時透明地將 Unicode 域標籤轉換為 IDNA,並在向用戶顯示之前將 ACE 標籤轉換回 Unicode。
Python 透過多種方式支援此轉換:idna
編解碼器執行 Unicode 和 ACE 之間的轉換,根據 RFC 3490 的 3.1 節 中定義的分隔符字元將輸入字串分成標籤,並根據需要將每個標籤轉換為 ACE,反之,則根據 .
分隔符將輸入位元組字串分成標籤,並將找到的任何 ACE 標籤轉換為 Unicode。此外,socket
模組透明地將 Unicode 主機名轉換為 ACE,因此當應用程式將主機名傳遞給 socket 模組時,無需擔心自己轉換主機名。最重要的是,將主機名作為函式引數的模組(例如 http.client
和 ftplib
)接受 Unicode 主機名(如果 http.client
傳送 Host 欄位,也會透明地在其中傳送 IDNA 主機名)。
當從網路接收主機名(例如在反向名稱查詢中)時,不會自動執行到 Unicode 的轉換:希望向使用者顯示此類主機名的應用程式應將其解碼為 Unicode。
模組 encodings.idna
還實現了 nameprep 過程,該過程對主機名執行某些規範化,以實現國際域名的不區分大小寫,並統一相似的字元。如果需要,可以直接使用 nameprep 函式。
- encodings.idna.nameprep(label)¶
返回 label 的 nameprep 版本。該實現當前假設為查詢字串,因此
AllowUnassigned
為 true。
encodings.mbcs
— Windows ANSI 內碼表¶
此模組實現 ANSI 內碼表 (CP_ACP)。
可用性:Windows。
在 3.2 版本中更改: 在 3.2 之前,errors 引數被忽略;'replace'
始終用於編碼,'ignore'
用於解碼。
在 3.3 版本中更改: 支援任何錯誤處理程式。
encodings.utf_8_sig
— 帶有 BOM 簽名的 UTF-8 編解碼器¶
此模組實現 UTF-8 編解碼器的一個變體。在編碼時,UTF-8 編碼的 BOM 將被新增到 UTF-8 編碼的位元組之前。對於有狀態編碼器,這隻執行一次(在第一次寫入位元組流時)。在解碼時,資料開頭的可選 UTF-8 編碼 BOM 將被跳過。