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

增量式編碼器和解碼器類或工廠函式。它們必須提供由基類 IncrementalEncoderIncrementalDecoder 定義的介面。增量式編解碼器可以保持狀態。

streamwriter
streamreader

流寫入器和讀取器類或工廠函式。 這些必須提供由基類 StreamWriterStreamReader 分別定義的介面。 流編解碼器可以維護狀態。

為了簡化對各種編解碼器元件的訪問,該模組提供了這些額外的函式,它們使用 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_UTF16BOM_UTF16_BEBOM_UTF16_LE,具體取決於平臺的本機位元組順序,BOMBOM_UTF16的別名,BOM_LEBOM_UTF16_LE的別名,BOM_BEBOM_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 標準編碼編解碼器

含義

'strict'

引發 UnicodeError(或其子類),這是預設值。在 strict_errors() 中實現。

'ignore'

忽略格式錯誤的資料,並繼續而不另行通知。在 ignore_errors() 中實現。

'replace'

替換為替換標記。在編碼時,使用 ?(ASCII 字元)。在解碼時,使用 (U+FFFD,官方 REPLACEMENT CHARACTER)。在 replace_errors() 中實現。

'backslashreplace'

替換為反斜槓轉義序列。在編碼時,使用格式為 \xhh \uxxxx \Uxxxxxxxx 的 Unicode 程式碼點的十六進位制形式。在解碼時,使用格式為 \xhh 的位元組值的十六進位制形式。在 backslashreplace_errors() 中實現。

'surrogateescape'

在解碼時,用介於 U+DC80U+DCFF 之間的單個代理程式碼替換位元組。當編碼資料時使用 'surrogateescape' 錯誤處理程式時,此程式碼將變回相同的位元組。(有關更多資訊,請參見 PEP 383。)

以下錯誤處理程式僅適用於編碼(在文字編碼中)

含義

'xmlcharrefreplace'

替換為 XML/HTML 數字字元引用,它是格式為 &#num; 的 Unicode 程式碼點的十進位制形式。在 xmlcharrefreplace_errors() 中實現。

'namereplace'

替換為 \N{...} 轉義序列,大括號中顯示的是 Unicode 字元資料庫中的 Name 屬性。在 namereplace_errors() 中實現。

此外,以下錯誤處理程式特定於給定的編解碼器

編解碼器

含義

'surrogatepass'

utf-8、utf-16、utf-32、utf-16-be、utf-16-le、utf-32-be、utf-32-le

允許將代理程式碼點(U+D800 - U+DFFF)編碼和解碼為普通程式碼點。否則,這些編解碼器會將 str 中出現代理程式碼點視為錯誤。

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 例項,其中包含關於錯誤位置的資訊。 錯誤處理控制代碼必須引發此異常或其他異常,或者返回一個元組,其中包含輸入中無法編碼部分的替換以及編碼應繼續的位置。 替換可以是 strbytes。 如果替換是位元組,則編碼器將直接將其複製到輸出緩衝區。 如果替換是字串,則編碼器將對替換進行編碼。 編碼將從指定位置的原始輸入繼續進行。 負位置值將被視為相對於輸入字串的末尾。 如果結果位置超出範圍,則會引發 IndexError

解碼和轉換的工作方式類似,只是 UnicodeDecodeErrorUnicodeTranslateError 將被傳遞給處理控制代碼,並且來自錯誤處理控制代碼的替換將直接放入輸出中。

以前註冊的錯誤處理控制代碼(包括標準錯誤處理控制代碼)可以透過名稱查詢

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 版本更改: 可以用於解碼和轉換。

codecs.xmlcharrefreplace_errors(exception)

實現 'xmlcharrefreplace' 錯誤處理(僅用於 文字編碼 中的編碼)。

無法編碼的字元將替換為適當的 XML/HTML 數字字元引用,它是 Unicode 程式碼點的十進位制形式,格式為 &#num;

codecs.namereplace_errors(exception)

實現 'namereplace' 錯誤處理(僅用於 文字編碼 中的編碼)。

無法編碼的字元將替換為 \N{...} 轉義序列。 花括號中出現的字元集是 Unicode 字元資料庫中的 Name 屬性。 例如,德語小寫字母 'ß' 將轉換為位元組序列 \N{LATIN SMALL LETTER SHARP S}

3.5 版本新增。

無狀態編碼和解碼

基本 Codec 類定義了這些方法,這些方法也定義了無狀態編碼器和解碼器的函式介面

class codecs.Codec
encode(input, errors='strict')

編碼物件 *input* 並返回一個元組(輸出物件,消耗的長度)。 例如,文字編碼 使用特定的字元集編碼(例如,cp1252iso-8859-1)將字串物件轉換為位元組物件。

*errors* 引數定義要應用的錯誤處理。 它預設為 'strict' 處理。

該方法可能不會在 Codec 例項中儲存狀態。 對於必須保持狀態才能使編碼高效的編解碼器,請使用 StreamWriter

編碼器必須能夠處理零長度輸入,並在這種情況下返回輸出物件型別的空物件。

decode(input, errors='strict')

解碼物件 *input* 並返回一個元組(輸出物件,消耗的長度)。 例如,對於 文字編碼,解碼會將使用特定字元集編碼編碼的位元組物件轉換為字串物件。

對於文字編碼和位元組到位元組的編解碼器,*input* 必須是一個位元組物件,或提供只讀緩衝區介面的物件,例如緩衝區物件和記憶體對映檔案。

*errors* 引數定義要應用的錯誤處理。 它預設為 'strict' 處理。

該方法可能不會在 Codec 例項中儲存狀態。 對於必須保持狀態才能使解碼高效的編解碼器,請使用 StreamReader

解碼器必須能夠處理零長度輸入,並在這種情況下返回輸出物件型別的空物件。

增量編碼和解碼

IncrementalEncoderIncrementalDecoder 類為增量編碼和解碼提供了基本介面。編碼/解碼輸入不是透過一次呼叫無狀態的編碼器/解碼器函式完成,而是透過多次呼叫增量編碼器/解碼器的 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() 返回的解碼器狀態。

流編碼和解碼

StreamWriterStreamReader 類提供了通用的工作介面,可以非常容易地使用這些介面來實現新的編碼子模組。有關如何執行此操作的示例,請參閱 encodings.utf_8

StreamWriter 物件

StreamWriter 類是 Codec 的子類,並定義了以下方法,每個流寫入器都必須定義這些方法才能與 Python 編解碼器登錄檔相容。

class codecs.StreamWriter(stream, errors='strict')

StreamWriter 例項的建構函式。

所有流寫入器都必須提供此建構函式介面。它們可以自由新增額外的關鍵字引數,但只有此處定義的引數會被 Python 編解碼器登錄檔使用。

*stream* 引數必須是一個類似於檔案的物件,該物件開啟用於寫入文字或二進位制資料,具體取決於特定的編解碼器。

StreamWriter 可以透過提供 *errors* 關鍵字引數來實現不同的錯誤處理方案。有關底層流編解碼器可能支援的標準錯誤處理程式,請參閱 錯誤處理程式

errors 引數將被賦值給同名的屬性。賦值給此屬性可以在 StreamWriter 物件的生命週期內切換不同的錯誤處理策略。

write(object)

將物件的內容編碼後寫入流。

writelines(list)

將字串的可迭代連線寫入流(可能透過重用 write() 方法)。不支援無限或非常大的可迭代物件。標準的位元組到位元組編解碼器不支援此方法。

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 必須是類似於檔案的物件。ReaderWriter 必須是提供 StreamReaderStreamWriter 介面的工廠函式或類。錯誤處理的方式與流讀取器和寫入器的定義方式相同。

StreamReaderWriter 例項定義了 StreamReaderStreamWriter 類的組合介面。它們繼承底層流的所有其他方法和屬性。

StreamRecoder 物件

StreamRecoder 將資料從一種編碼轉換為另一種編碼,這在處理不同的編碼環境時有時很有用。

其設計方式使得可以使用 lookup() 函式返回的工廠函式來構造例項。

class codecs.StreamRecoder(stream, encode, decode, Reader, Writer, errors='strict')

建立一個 StreamRecoder 例項,該例項實現雙向轉換:encodedecode 在前端工作 — 對呼叫 read()write() 的程式碼可見的資料進行操作,而 ReaderWriter 在後端工作 — 對 stream 中的資料進行操作。

您可以使用這些物件進行透明的轉碼,例如從 Latin-1 到 UTF-8 並返回。

stream 引數必須是類檔案物件。

encodedecode 引數必須符合 Codec 介面。ReaderWriter 必須是工廠函式或類,分別提供 StreamReaderStreamWriter 介面的物件。

錯誤處理的方式與為流讀取器和寫入器定義的方式相同。

StreamRecoder 例項定義了 StreamReaderStreamWriter 類的組合介面。它們從底層流繼承所有其他方法和屬性。

編碼和 Unicode

字串在內部儲存為程式碼點序列,範圍為 U+0000U+10FFFF。(有關實現的更多詳細資訊,請參閱 PEP 393。)一旦字串物件在 CPU 和記憶體之外使用,位元組序以及這些陣列如何儲存為位元組就成為問題。與其他編解碼器一樣,將字串序列化為位元組序列稱為編碼,而從位元組序列重建字串稱為解碼。有各種不同的文字序列化編解碼器,它們統稱為文字編碼

最簡單的文字編碼(稱為 'latin-1''iso-8859-1')將程式碼點 0–255 對映到位元組 0x00xff,這意味著包含高於 U+00FF 的程式碼點的字串物件無法使用此編解碼器進行編碼。這樣做會引發 UnicodeEncodeError,如下所示(儘管錯誤訊息的詳細資訊可能有所不同): UnicodeEncodeError: 'latin-1' codec can't encode character '\u1234' in position 3: ordinal not in range(256)

還有另一組編碼(所謂的字元對映編碼)選擇所有 Unicode 程式碼點的不同子集,以及這些程式碼點如何對映到位元組 0x00xff。要了解如何做到這一點,只需開啟例如 encodings/cp1252.py(它主要在 Windows 上使用的一種編碼)。有一個包含 256 個字元的字串常量,它顯示哪個字元對映到哪個位元組值。

所有這些編碼只能編碼 Unicode 中定義的 1114112 個程式碼點中的 256 個。一種可以儲存每個 Unicode 程式碼點的簡單直接的方法是將每個程式碼點儲存為四個連續的位元組。有兩種可能性:以大端或小端順序儲存位元組。這兩種編碼分別稱為 UTF-32-BEUTF-32-LE。它們的缺點是,例如,如果在小端機器上使用 UTF-32-BE,則始終需要在編碼和解碼時交換位元組。UTF-32 避免了這個問題:位元組始終處於自然位元組序。當具有不同位元組序的 CPU 讀取這些位元組時,必須交換位元組。為了能夠檢測 UTF-16UTF-32 位元組序列的位元組序,有所謂的 BOM(“位元組順序標記”)。這是 Unicode 字元 U+FEFF。此字元可以新增到每個 UTF-16UTF-32 位元組序列。此字元的位元組交換版本 (0xFFFE) 是一個非法字元,不得出現在 Unicode 文字中。因此,當 UTF-16UTF-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 字元)

範圍

編碼

U-00000000U-0000007F

0xxxxxxx

U-00000080U-000007FF

110xxxxx 10xxxxxx

U-00000800U-0000FFFF

1110xxxx 10xxxxxx 10xxxxxx

U-00010000U-0010FFFF

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(作為位元組序列如下所示:0xef0xbb0xbf)。由於任何字元對映編碼檔案都不太可能以這些位元組值開頭(例如,這將對映到

帶分音符的拉丁小寫字母 I
右指雙角引號
倒問號

在 iso-8859-1 中),這增加了從位元組序列中正確猜測 utf-8-sig 編碼的可能性。因此,這裡的 BOM 不是用來確定生成位元組序列所使用的位元組順序,而是作為一種有助於猜測編碼的簽名。在編碼時,utf-8-sig 編解碼器會將 0xef0xbb0xbf 作為前三個位元組寫入檔案。在解碼時,如果 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+D800U+DFFF)。utf-32* 解碼器不再解碼對應於代理程式碼點的位元組序列。

在 3.8 版本中更改:cp65001 現在是 utf_8 的別名。

Python 特定編碼

許多預定義的編解碼器是 Python 特有的,因此它們的編解碼器名稱在 Python 之外沒有意義。它們在下表中根據預期的輸入和輸出型別列出(請注意,雖然文字編碼是編解碼器最常見的用例,但底層編解碼器基礎結構支援任意資料轉換,而不僅僅是文字編碼)。對於不對稱編解碼器,所述含義描述了編碼方向。

文字編碼

以下編解碼器提供 strbytes 編碼和 類似位元組物件str 解碼,類似於 Unicode 文字編碼。

Codec

別名

含義

idna

實現 RFC 3490,另請參閱 encodings.idna。僅支援 errors='strict'

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 編碼,其他程式碼點使用 \uXXXX\UXXXXXXXX。現有的反斜槓不會以任何方式轉義。它用於 Python pickle 協議中。

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 格式(結果始終包含尾部的 '\n')。

在 3.4 版本中更改: 接受任何 類位元組物件 作為編碼和解碼的輸入。

base64.encodebytes() / base64.decodebytes()

bz2_codec

bz2

使用 bz2 壓縮運算元。

bz2.compress() / bz2.decompress()

hex_codec

hex

將運算元轉換為十六進位制表示,每個位元組使用兩位數字。

binascii.b2a_hex() / binascii.a2b_hex()

quopri_codec

quopri, quotedprintable, quoted_printable

將運算元轉換為 MIME quoted printable 格式。

quopri.encode(),其中 quotetabs=True / quopri.decode()

uu_codec

uu

使用 uuencode 轉換運算元。

zlib_codec

zip, zlib

使用 gzip 壓縮運算元。

zlib.compress() / zlib.decompress()

在 3.2 版本中加入: 恢復了二進位制轉換。

在 3.4 版本中更改: 恢復了二進位制轉換的別名。

文字轉換

以下編解碼器提供文字轉換:strstr 的對映。它不受 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 5891RFC 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.clientftplib)接受 Unicode 主機名(如果 http.client 傳送 Host 欄位,也會透明地在其中傳送 IDNA 主機名)。

當從網路接收主機名(例如在反向名稱查詢中)時,不會自動執行到 Unicode 的轉換:希望向使用者顯示此類主機名的應用程式應將其解碼為 Unicode。

模組 encodings.idna 還實現了 nameprep 過程,該過程對主機名執行某些規範化,以實現國際域名的不區分大小寫,並統一相似的字元。如果需要,可以直接使用 nameprep 函式。

encodings.idna.nameprep(label)

返回 label 的 nameprep 版本。該實現當前假設為查詢字串,因此 AllowUnassigned 為 true。

encodings.idna.ToASCII(label)

按照 RFC 3490 中的規定將標籤轉換為 ASCII。UseSTD3ASCIIRules 被假定為 false。

encodings.idna.ToUnicode(label)

按照 RFC 3490 中的規定將標籤轉換為 Unicode。

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 將被跳過。