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.charmap_build(string)¶
返回一個適合使用自定義單位元組編碼進行編碼的對映。給定一個最多 256 個字元的
str
string,表示一個解碼錶,返回一個緊湊的內部對映物件EncodingMap
或一個將字元序數值對映到位元組值的字典
。對無效輸入引發TypeError
。
每個編解碼器的完整詳細資訊也可以直接查詢
- 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'
模式已移除。自 3.14 版棄用:
codecs.open()
已被open()
取代。
- 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 提供的輸入。iterator 必須生成
str
物件。此函式是一個生成器。errors 引數(以及任何其他關鍵字引數)會傳遞給增量編碼器。此函式要求編解碼器接受文字
str
物件進行編碼。因此,它不支援位元組到位元組的編碼器,例如base64_codec
。
- codecs.iterdecode(iterator, encoding, errors='strict', **kwargs)¶
使用增量解碼器迭代解碼由 iterator 提供的輸入。iterator 必須生成
bytes
物件。此函式是一個生成器。errors 引數(以及任何其他關鍵字引數)會傳遞給增量解碼器。此函式要求編解碼器接受
bytes
物件進行解碼。因此,它不支援文字到文字的編碼器,例如rot_13
,儘管rot_13
可以與iterencode()
等效使用。
- codecs.readbuffer_encode(buffer, errors=None, /)¶
返回一個
tuple
,其中包含 buffer(一個緩衝區相容物件或str
,在處理前編碼為 UTF-8)的原始位元組及其位元組長度。errors 引數被忽略。
>>> codecs.readbuffer_encode(b"Zito") (b'Zito', 4)
該模組還提供以下常量,這些常量對於讀寫平臺相關檔案很有用
- 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 標準編碼 編解碼器
值 |
含義 |
---|---|
|
引發 |
|
忽略格式錯誤的資料並繼續,不作進一步通知。在 |
|
替換為替換標記。編碼時,使用 |
|
替換為反斜槓轉義序列。編碼時,使用 Unicode 碼點的十六進位制形式,格式為 |
|
解碼時,用範圍從 |
以下錯誤處理程式僅適用於編碼(在文字編碼內)
值 |
含義 |
---|---|
|
替換為 XML/HTML 數字字元引用,它是 Unicode 碼點的十進位制形式,格式為 |
|
替換為 |
此外,以下錯誤處理程式特定於給定的編解碼器
值 |
編解碼器 |
含義 |
---|---|---|
|
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。
對於編碼,將使用
UnicodeEncodeError
例項呼叫 error_handler,該例項包含有關錯誤位置的資訊。錯誤處理程式必須要麼引發此異常或不同的異常,要麼返回一個元組,其中包含不可編碼部分的替換以及編碼應繼續的位置。替換可以是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'
錯誤處理。格式錯誤的資料被反斜槓轉義序列替換。編碼時,使用 Unicode 碼點的十六進位制形式,格式為
\xhh
\uxxxx
\Uxxxxxxxx
。解碼時,使用位元組值的十六進位制形式,格式為\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
是最常見的狀態。(比整數更復雜的狀態可以透過對狀態進行編組/醃製並將結果字串的位元組編碼為整數來轉換為整數。)
- 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
的狀態,以便將先前緩衝的輸入提供給解碼器會將其恢復到以前的狀態而不產生任何輸出。(比整數更復雜的附加狀態資訊可以透過對資訊進行編組/醃製並將結果字串的位元組編碼為整數來轉換為整數。)
- 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
物件的生命週期內切換不同的錯誤處理策略。errors 引數允許的值集可以透過
register_error()
進行擴充套件。- 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
(WORD JOINER
) 取代此角色)。儘管如此,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
)。由於任何字元對映編碼檔案不太可能以這些位元組值開頭(例如,它們在 iso-8859-1 中會對映到
帶分音符的拉丁小寫字母 I右指向雙角引號反問號
),這增加了從位元組序列正確猜測 utf-8-sig
編碼的可能性。因此,這裡的 BOM 不是用來確定生成位元組序列所使用的位元組順序,而是作為有助於猜測編碼的簽名。在編碼時,utf-8-sig 編解碼器將 0xef
、0xbb
、0xbf
作為前三個位元組寫入檔案。在解碼時,如果這些位元組作為檔案中的前三個位元組出現,utf-8-sig
將跳過這些位元組。在 UTF-8 中,不鼓勵使用 BOM,通常應避免使用。
標準編碼¶
Python 內建了許多編解碼器,它們或以 C 函式實現,或以字典作為對映表。下表列出了按名稱列出的編解碼器,以及一些常用別名和可能使用該編碼的語言。別名列表和語言列表均不旨在窮盡。請注意,大小寫不同或使用連字元而不是下劃線的拼寫替代也是有效別名,因為它們在透過 normalize_encoding()
規範化後是等效的。例如,'utf-8'
是 'utf_8'
編解碼器的有效別名。
備註
下表列出了最常見的別名,完整的列表請參閱源 aliases.py 檔案。
在 Windows 上,所有內碼表都提供 cpXXX
編解碼器。但只有下表中列出的編解碼器才保證在其他平臺上存在。
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 相容
編解碼器 |
別名 |
語言 |
---|---|---|
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, cyrillic |
白俄羅斯語、保加利亞語、馬其頓語、俄語、塞爾維亞語 |
iso8859_6 |
iso-8859-6, arabic |
阿拉伯語 |
iso8859_7 |
iso-8859-7, greek, greek8 |
希臘語 |
iso8859_8 |
iso-8859-8, hebrew |
希伯來語 |
iso8859_9 |
iso-8859-9, latin5, L5 |
土耳其語 |
iso8859_10 |
iso-8859-10, latin6, L6 |
北歐語言 |
iso8859_11 |
iso-8859-11, thai |
泰語 |
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
的別名。
3.14 版本發生變化: 在 Windows 上,所有內碼表現在都提供 cpXXX
編解碼器。
Python 特有編碼¶
一些預定義的編解碼器是 Python 特有的,因此它們的編解碼器名稱在 Python 之外沒有意義。這些編解碼器根據預期的輸入和輸出型別列在下表中(請注意,雖然文字編碼是編解碼器最常見的用例,但底層編解碼器基礎設施支援任意資料轉換,而不僅僅是文字編碼)。對於不對稱編解碼器,所述含義描述了編碼方向。
文字編碼¶
以下編解碼器提供 str
到 bytes
的編碼和 位元組類物件 到 str
的解碼,類似於 Unicode 文字編碼。
編解碼器 |
別名 |
含義 |
---|---|---|
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
輸出)。
編解碼器 |
別名 |
含義 |
編碼器/解碼器 |
---|---|---|---|
base64_codec [1] |
base64, base_64 |
將運算元轉換為多行 MIME base64(結果始終包含一個尾隨 3.4 版本發生變化: 編碼和解碼接受任何 位元組類物件 作為輸入 |
|
bz2_codec |
bz2 |
使用 bz2 壓縮運算元。 |
|
hex_codec |
hex |
將運算元轉換為十六進位制表示,每位元組兩位數字。 |
|
quopri_codec |
quopri, quotedprintable, quoted_printable |
將運算元轉換為 MIME 帶引號可列印。 |
|
uu_codec |
uu |
使用 uuencode 轉換運算元。 |
|
zlib_codec |
zip, zlib |
使用 gzip 壓縮運算元。 |
3.2 新增: 恢復了二進位制轉換。
3.4 版本發生變化: 恢復了二進位制轉換的別名。
獨立編解碼器函式¶
以下函式提供類似於編解碼器的編碼和解碼功能,但不能透過 codecs.encode()
或 codecs.decode()
作為命名編解碼器使用。它們在內部使用(例如,透過 pickle
),其行為類似於 Python 3 中已移除的 string_escape
編解碼器。
文字轉換¶
以下編解碼器提供文字轉換:str
到 str
的對映。它不支援 str.encode()
(它只生成 bytes
輸出)。
編解碼器 |
別名 |
含義 |
---|---|---|
rot_13 |
rot13 |
返回運算元的凱撒密碼加密。 |
3.2 新增: 恢復了 rot_13
文字轉換。
3.4 版本發生變化: 恢復了 rot13
別名。
encodings
— 編碼包¶
本模組實現了以下函式
- encodings.normalize_encoding(encoding)¶
規範化編碼名稱 encoding。
規範化工作方式如下:除了用於 Python 包名的點之外,所有非字母數字字元都被摺疊並替換為單個下劃線,開頭的和尾隨的下劃線被刪除。例如,
' -;#'
變為'_'
。請注意,encoding 應僅包含 ASCII 字元。
備註
以下函式不應直接使用,除非用於測試目的;應改用 codecs.lookup()
。
- encodings.search_function(encoding)¶
搜尋與給定編碼名稱 encoding 對應的編解碼器模組。
此函式首先使用
normalize_encoding()
規範化 encoding,然後查詢相應的別名。它嘗試使用別名或規範化名稱從 encodings 包中匯入編解碼器模組。如果找到模組並定義了有效的getregentry()
函式,該函式返回一個codecs.CodecInfo
物件,則編解碼器將被快取並返回。如果編解碼器模組定義了
getaliases()
函式,則任何返回的別名都將註冊以供將來使用。
- encodings.win32_code_page_search_function(encoding)¶
搜尋
cpXXXX
形式的 Windows 內碼表編碼 encoding。如果內碼表有效且受支援,則返回其
codecs.CodecInfo
物件。可用性: Windows。
在 3.14 版本加入。
本模組實現了以下異常
- exception encodings.CodecRegistryError¶
當編解碼器無效或不相容時引發。
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 的 nameprepped 版本。當前實現假定查詢字串,因此
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。