codecs --- 編解碼器注冊和相關基類?
源代碼: Lib/codecs.py
這個模塊定義了標準 Python 編解碼器(編碼器和解碼器)的基類,并提供接口用來訪問內部的 Python 編解碼器注冊表,該注冊表負責管理編解碼器和錯誤處理的查找過程。 大多數(shù)標準編解碼器都屬于 文本編碼,它們可將文本編碼為字節(jié)串,但也提供了一些編解碼器可將文本編碼為文本,以及字節(jié)串編碼為字節(jié)串。 自定義編解碼器可以在任意類型間進行編碼和解碼,但某些模塊特性僅適用于 文本編碼 或將數(shù)據(jù)編碼為 字節(jié)串 的編解碼器。
該模塊定義了以下用于使用任何編解碼器進行編碼和解碼的函數(shù):
-
codecs.encode(obj, encoding='utf-8', errors='strict')? 使用為 encoding 注冊的編解碼器對 obj 進行編碼。
可以給定 Errors 以設置所需要的錯誤處理方案。 默認的錯誤處理方案
'strict'表示編碼錯誤將引發(fā)ValueError(或更特定編解碼器相關的子類,例如UnicodeEncodeError)。 請參閱 編解碼器基類 了解有關編解碼器錯誤處理的更多信息。
-
codecs.decode(obj, encoding='utf-8', errors='strict')? 使用為 encoding 注冊的編解碼器對 obj 進行解碼。
可以給定 Errors 以設置所需要的錯誤處理方案。 默認的錯誤處理方案
'strict'表示編碼錯誤將引發(fā)ValueError(或更特定編解碼器相關的子類,例如UnicodeDecodeError)。 請參閱 編解碼器基類 了解有關編解碼器錯誤處理的更多信息。
每種編解碼器的完整細節(jié)也可以直接查找獲取:
-
codecs.lookup(encoding)? 在 Python 編解碼器注冊表中查找編解碼器信息,并返回一個
CodecInfo對象,其定義見下文。首先將會在注冊表緩存中查找編碼,如果未找到,則會掃描注冊的搜索函數(shù)列表。 如果沒有找到
CodecInfo對象,則將引發(fā)LookupError。 否則,CodecInfo對象將被存入緩存并返回給調用者。
-
class
codecs.CodecInfo(encode, decode, streamreader=None, streamwriter=None, incrementalencoder=None, incrementaldecoder=None, name=None)? 查找編解碼器注冊表所得到的編解碼器細節(jié)信息。 構造器參數(shù)將保存為同名的屬性:
-
name? 編碼名稱
-
encode? -
decode? 無狀態(tài)的編碼和解碼函數(shù)。 它們必須是具有與 Codec 的
encode()和decode()方法相同接口的函數(shù)或方法 (參見 Codec 接口)。 這些函數(shù)或方法應當工作于無狀態(tài)的模式。
-
incrementalencoder? -
incrementaldecoder? 增量式的編碼器和解碼器類或工廠函數(shù)。 這些函數(shù)必須分別提供由基類
IncrementalEncoder和IncrementalDecoder所定義的接口。 增量式編解碼器可以保持狀態(tài)。
-
streamwriter? -
streamreader? 流式寫入器和讀取器類或工廠函數(shù)。 這些函數(shù)必須分別提供由基類
StreamWriter和StreamReader所定義的接口。 流式編解碼器可以保持狀態(tài)。
-
為了簡化對各種編解碼器組件的訪問,本模塊提供了以下附加函數(shù),它們使用 lookup() 來執(zhí)行編解碼器查找:
-
codecs.getencoder(encoding)? 查找給定編碼的編解碼器并返回其編碼器函數(shù)。
在編碼無法找到時將引發(fā)
LookupError。
-
codecs.getdecoder(encoding)? 查找給定編碼的編解碼器并返回其解碼器函數(shù)。
在編碼無法找到時將引發(fā)
LookupError。
-
codecs.getincrementalencoder(encoding)? 查找給定編碼的編解碼器并返回其增量式編碼器類或工廠函數(shù)。
在編碼無法找到或編解碼器不支持增量式編碼器時將引發(fā)
LookupError。
-
codecs.getincrementaldecoder(encoding)? 查找給定編碼的編解碼器并返回其增量式解碼器類或工廠函數(shù)。
在編碼無法找到或編解碼器不支持增量式解碼器時將引發(fā)
LookupError。
-
codecs.getreader(encoding)? 查找給定編碼的編解碼器并返回其
StreamReader類或工廠函數(shù)。在編碼無法找到時將引發(fā)
LookupError。
-
codecs.getwriter(encoding)? 查找給定編碼的編解碼器并返回其
StreamWriter類或工廠函數(shù)。在編碼無法找到時將引發(fā)
LookupError。
自定義編解碼器的啟用是通過注冊適當?shù)木幗獯a器搜索函數(shù):
-
codecs.register(search_function)? 注冊一個編解碼器搜索函數(shù)。 搜索函數(shù)預期接收一個參數(shù),即全部以小寫字母表示的編碼名稱,并返回一個
CodecInfo對象。 在搜索函數(shù)無法找到給定編碼的情況下,它應當返回None。注解
搜索函數(shù)的注冊目前是不可逆的,這在某些情況下可能導致問題,例如單元測試或模塊重載等。
雖然內置的 open() 和相關聯(lián)的 io 模塊是操作已編碼文本文件的推薦方式,但本模塊也提供了額外的工具函數(shù)和類,允許在操作二進制文件時使用更多各類的編解碼器:
-
codecs.open(filename, mode='r', encoding=None, errors='strict', buffering=1)? 使用給定的 mode 打開已編碼的文件并返回一個
StreamReaderWriter的實例,提供透明的編碼/解碼。 默認的文件模式為'r',表示以讀取模式打開文件。注解
下層的已編碼文件總是以二進制模式打開。 在讀取和寫入時不會自動執(zhí)行
'\n'的轉換。 mode 參數(shù)可以是內置open()函數(shù)所接受的任意二進制模式;'b'會被自動添加。encoding 指定文件所要使用的編碼格式。 允許任何編碼為字節(jié)串或從字節(jié)串解碼的編碼格式,而文件方法所支持的數(shù)據(jù)類型則取決于所使用的編解碼器。
可以指定 errors 來定義錯誤處理方案。 默認值
'strict'表示在出現(xiàn)編碼錯誤時引發(fā)ValueError。buffering 的含義與內置
open()函數(shù)中的相同。 默認為行緩沖。
-
codecs.EncodedFile(file, data_encoding, file_encoding=None, errors='strict')? 返回一個
StreamRecoder實例,它提供了 file 的透明轉碼包裝版本。 當包裝版本被關閉時原始文件也會被關閉。寫入已包裝文件的數(shù)據(jù)會根據(jù)給定的 data_encoding 解碼,然后以使用 file_encoding 的字節(jié)形式寫入原始文件。 從原始文件讀取的字節(jié)串將根據(jù) file_encoding 解碼,其結果將使用 data_encoding 進行編碼。
如果 file_encoding 未給定,則默認為 data_encoding。
可以指定 errors 來定義錯誤處理方案。 默認值
'strict'表示在出現(xiàn)編碼錯誤時引發(fā)ValueError。
-
codecs.iterencode(iterator, encoding, errors='strict', **kwargs)? 使用增量式編碼器通過迭代來編碼由 iterator 所提供的輸入。 此函數(shù)屬于 generator。 errors 參數(shù)(以及任何其他關鍵字參數(shù))會被傳遞給增量式編碼器。
此函數(shù)要求編解碼器接受
str對象形式的文本進行編碼。 因此它不支持字節(jié)到字節(jié)的編碼器,例如base64_codec。
-
codecs.iterdecode(iterator, encoding, errors='strict', **kwargs)? 使用增量式解碼器通過迭代來解碼由 iterator 所提供的輸入。 此函數(shù)屬于 generator。 errors 參數(shù)(以及任何其他關鍵字參數(shù))會被傳遞給增量式解碼器。
此函數(shù)要求編解碼器接受
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? 這些常量定義了多種字節(jié)序列,即一些編碼格式的 Unicode 字節(jié)順序標記(BOM)。 它們在 UTF-16 和 UTF-32 數(shù)據(jù)流中被用以指明所使用的字節(jié)順序,并在 UTF-8 中被用作 Unicode 簽名。
BOM_UTF16是BOM_UTF16_BE或BOM_UTF16_LE,具體取決于平臺的本機字節(jié)順序,BOM是BOM_UTF16的別名,BOM_LE是BOM_UTF16_LE的別名,BOM_BE是BOM_UTF16_BE的別名。 其他序列則表示 UTF-8 和 UTF-32 編碼格式中的 BOM。
編解碼器基類?
codecs 模塊定義了一系列基類用來定義配合編解碼器對象進行工作的接口,并且也可用作定制編解碼器實現(xiàn)的基礎。
每種編解碼器必須定義四個接口以便用作 Python 中的編解碼器:無狀態(tài)編碼器、無狀態(tài)解碼器、流讀取器和流寫入器。 流讀取器和寫入器通常會重用無狀態(tài)編碼器/解碼器來實現(xiàn)文件協(xié)議。 編解碼器作者還需要定義編解碼器將如何處理編碼和解碼錯誤。
錯誤處理方案?
為了簡化和標準化錯誤處理,編解碼器可以通過接受 errors 字符串參數(shù)來實現(xiàn)不同的錯誤處理方案。 所有標準的 Python 編解碼器都定義并實現(xiàn)了以下字符串值:
值 |
含義 |
|---|---|
|
引發(fā) |
|
忽略錯誤格式的數(shù)據(jù)并且不加進一步通知就繼續(xù)執(zhí)行。 在 |
以下錯誤處理方案僅適用于 文本編碼:
值 |
含義 |
|---|---|
|
使用適當?shù)奶鎿Q標記進行替換;Python 內置編解碼器將在解碼時使用官方 |
|
使用適當?shù)?XML 字符引用進行替換(僅在編碼時)。 在 |
|
使用帶反斜杠的轉義序列進行替換。 在 |
|
使用 |
|
在解碼時,將字節(jié)替換為 |
此外,以下錯誤處理方案被專門用于指定的編解碼器:
值 |
編解碼器 |
含義 |
|---|---|---|
|
utf-8, utf-16, utf-32, utf-16-be, utf-16-le, utf-32-be, utf-32-le |
允許編碼和解碼代理代碼。 這些編解碼器通常會將出現(xiàn)的代理代碼視為錯誤。 |
3.1 新版功能: 'surrogateescape' 和 'surrogatepass' 錯誤處理方案。
在 3.4 版更改: 'surrogatepass' 錯誤處理方案現(xiàn)在適用于 utf-16* 和 utf-32* 編解碼器。
3.5 新版功能: 'namereplace' 錯誤處理方案。
在 3.5 版更改: 'backslashreplace' 錯誤處理方案現(xiàn)在適用于解碼和轉換。
允許的值集合可以通過注冊新命名的錯誤處理方案來擴展:
-
codecs.register_error(name, error_handler)? 在名稱 name 之下注冊錯誤處理函數(shù) error_handler。 當 name 被指定為錯誤形參時,error_handler 參數(shù)所指定的對象將在編碼和解碼期間發(fā)生錯誤的情況下被調用,
對于編碼操作,將會調用 error_handler 并傳入一個
UnicodeEncodeError實例,其中包含有關錯誤位置的信息。 錯誤處理程序必須引發(fā)此異常或別的異常,或者也可以返回一個元組,其中包含輸入的不可編碼部分的替換對象,以及應當繼續(xù)進行編碼的位置。 替換對象可以為str或bytes類型。 如果替換對象為字節(jié)串,編碼器將簡單地將其復制到輸出緩沖區(qū)。 如果替換對象為字符串,編碼器將對替換對象進行編碼。 對原始輸入的編碼操作會在指定位置繼續(xù)進行。 負的位置值將被視為相對于輸入字符串的末尾。 如果結果位置超出范圍則將引發(fā)IndexError。解碼和轉換的做法很相似,不同之處在于將把
UnicodeDecodeError或UnicodeTranslateError傳給處理程序,并且來自錯誤處理程序的替換對象將被直接放入輸出。
之前注冊的錯誤處理方案(包括標準錯誤處理方案)可通過名稱進行查找:
-
codecs.lookup_error(name)? 返回之前在名稱 name 之下注冊的錯誤處理方案。
在處理方案無法找到時將引發(fā)
LookupError。
以下標準錯誤處理方案也可通過模塊層級函數(shù)的方式來使用:
-
codecs.strict_errors(exception)? 實現(xiàn)
'strict'錯誤處理方案:每個編碼或解碼錯誤都會引發(fā)UnicodeError。
-
codecs.replace_errors(exception)? 實現(xiàn)
'replace'錯誤處理方案 (僅用于 文本編碼):編碼錯誤替換為'?'(并由編解碼器編碼),解碼錯誤替換為'\ufffd'(Unicode 替換字符)。
-
codecs.ignore_errors(exception)? 實現(xiàn)
'ignore'錯誤處理方案:忽略錯誤格式的數(shù)據(jù)并且不加進一步通知就繼續(xù)執(zhí)行。
-
codecs.xmlcharrefreplace_errors(exception)? 實現(xiàn)
'xmlcharrefreplace'錯誤處理方案 (僅用于 文本編碼 的編碼過程):不可編碼的字符將以適當?shù)?XML 字符引用進行替換。
無狀態(tài)的編碼和解碼?
基本 Codec 類定義了這些方法,同時還定義了無狀態(tài)編碼器和解碼器的函數(shù)接口:
-
Codec.encode(input[, errors])? 編碼 input 對象并返回一個元組 (輸出對象, 消耗長度)。 例如,text encoding 會使用特定的字符集編碼格式 (例如
cp1252或iso-8859-1) 將字符串轉換為字節(jié)串對象。errors 參數(shù)定義了要應用的錯誤處理方案。 默認為
'strict'處理方案。此方法不一定會在
Codec實例中保存狀態(tài)。 可使用必須保存狀態(tài)的StreamWriter作為編解碼器以便高效地進行編碼。編碼器必須能夠處理零長度的輸入并在此情況下返回輸出對象類型的空對象。
-
Codec.decode(input[, errors])? 解碼 input 對象并返回一個元組 (輸出對象, 消耗長度)。 例如,text encoding 的解碼操作會使用特定的字符集編碼格式將字節(jié)串對象轉換為字符串對象。
對于文本編碼格式和字節(jié)到字節(jié)編解碼器,input 必須為一個字節(jié)串對象或提供了只讀緩沖區(qū)接口的對象 -- 例如,緩沖區(qū)對象和映射到內存的文件。
errors 參數(shù)定義了要應用的錯誤處理方案。 默認為
'strict'處理方案。此方法不一定會在
Codec實例中保存狀態(tài)。 可使用必須保存狀態(tài)的StreamReader作為編解碼器以便高效地進行解碼。解碼器必須能夠處理零長度的輸入并在此情況下返回輸出對象類型的空對象。
增量式的編碼和解碼?
IncrementalEncoder 和 IncrementalDecoder 類提供了增量式編碼和解碼的基本接口。 對輸入的編碼/解碼不是通過對無狀態(tài)編碼器/解碼器的一次調用,而是通過對增量式編碼器/解碼器的 encode()/decode() 方法的多次調用。 增量式編碼器/解碼器會在方法調用期間跟蹤編碼/解碼過程。
調用 encode()/decode() 方法后的全部輸出相當于將所有通過無狀態(tài)編碼器/解碼器進行編碼/解碼的單個輸入連接在一起所得到的輸出。
IncrementalEncoder 對象?
IncrementalEncoder 類用來對一個輸入進行分步編碼。 它定義了以下方法,每個增量式編碼器都必須定義這些方法以便與 Python 編解碼器注冊表相兼容。
-
class
codecs.IncrementalEncoder(errors='strict')? IncrementalEncoder實例的構造器。所有增量式編碼器必須提供此構造器接口。 它們可以自由地添加額外的關鍵字參數(shù),但只有在這里定義的參數(shù)才會被 Python 編解碼器注冊表所使用。
IncrementalEncoder可以通過提供 errors 關鍵字參數(shù)來實現(xiàn)不同的錯誤處理方案。 可用的值請參閱 錯誤處理方案。errors 參數(shù)將被賦值給一個同名的屬性。 通過對此屬性賦值就可以在
IncrementalEncoder對象的生命期內在不同的錯誤處理策略之間進行切換。-
encode(object[, final])? 編碼 object (會將編碼器的當前狀態(tài)納入考慮) 并返回已編碼的結果對象。 如果這是對
encode()的最終調用則 final 必須為真值(默認為假值)。
-
reset()? 將編碼器重置為初始狀態(tài)。 輸出將被丟棄:調用
.encode(object, final=True),在必要時傳入一個空字節(jié)串或字符串,重置編碼器并得到輸出。
-
getstate()? 返回編碼器的當前狀態(tài),該值必須為一個整數(shù)。 實現(xiàn)應當確保
0是最常見的狀態(tài)。 (比整數(shù)更復雜的狀態(tài)表示可以通過編組/選擇狀態(tài)并將結果字符串的字節(jié)數(shù)據(jù)編碼為整數(shù)來轉換為一個整數(shù)值)。
-
setstate(state)? 將編碼器的狀態(tài)設為 state。 state 必須為
getstate()所返回的一個編碼器狀態(tài)。
-
IncrementalDecoder 對象?
IncrementalDecoder 類用來對一個輸入進行分步解碼。 它定義了以下方法,每個增量式解碼器都必須定義這些方法以便與 Python 編解碼器注冊表相兼容。
-
class
codecs.IncrementalDecoder(errors='strict')? IncrementalDecoder實例的構造器。所有增量式解碼器必須提供此構造器接口。 它們可以自由地添加額外的關鍵字參數(shù),但只有在這里定義的參數(shù)才會被 Python 編解碼器注冊表所使用。
IncrementalDecoder可以通過提供 errors 關鍵字參數(shù)來實現(xiàn)不同的錯誤處理方案。 可用的值請參閱 錯誤處理方案。errors 參數(shù)將被賦值給一個同名的屬性。 通過對此屬性賦值就可以在
IncrementalDecoder對象的生命期內在不同的錯誤處理策略之間進行切換。-
decode(object[, final])? 解碼 object (會將解碼器的當前狀態(tài)納入考慮) 并返回已解碼的結果對象。 如果這是對
decode()的最終調用則 final 必須為真值(默認為假值)。 如果 final 為真值則解碼器必須對輸入進行完全解碼并且必須 刷新所有緩沖區(qū)。 如果這無法做到(例如由于在輸入結束時字節(jié)串序列不完整)則它必須像在無狀態(tài)的情況下那樣初始化錯誤處理(這可能引發(fā)一個異常)。
-
reset()? 將解碼器重置為初始狀態(tài)。
-
getstate()? 返回解碼器的當前狀態(tài)。 這必須為一個二元組,第一項必須是包含尚未解碼的輸入的緩沖區(qū)。 第二項必須為一個整數(shù),可以表示附加狀態(tài)信息。 (實現(xiàn)應當確保
0是最常見的附加狀態(tài)信息。) 如果此附加狀態(tài)信息為0則必須可以將解碼器設為沒有已緩沖輸入并且以0作為附加狀態(tài)信息,以便將先前已緩沖的輸入饋送到解碼器使其返回到先前的狀態(tài)而不產生任何輸出。 (比整數(shù)更復雜的附加狀態(tài)信息可以通過編組/選擇狀態(tài)信息并將結果字符串的字節(jié)數(shù)據(jù)編碼為整數(shù)來轉換為一個整數(shù)值。)
-
setstate(state)? 將解碼器的狀態(tài)設為 state。 state 必須為
getstate()所返回的一個解碼器狀態(tài)。
-
流式的編碼和解碼?
StreamWriter 和 StreamReader 類提供了一些泛用工作接口,可被用來非常方便地實現(xiàn)新的編碼格式子模塊。 請參閱 encodings.utf_8 中的示例了解如何做到這一點。
StreamWriter 對象?
StreamWriter 類是 Codec 的子類,它定義了以下方法,每個流式寫入器都必須定義這些方法以便與 Python 編解碼器注冊表相兼容。
-
class
codecs.StreamWriter(stream, errors='strict')? StreamWriter實例的構造器。所有流式寫入器必須提供此構造器接口。 它們可以自由地添加額外的關鍵字參數(shù),但只有在這里定義的參數(shù)才會被 Python 編解碼器注冊表所使用。
stream 參數(shù)必須為一個基于特定編解碼器打開用于寫入文本或二進制數(shù)據(jù)的文件類對象。
StreamWriter可以通過提供 errors 關鍵字參數(shù)來實現(xiàn)不同的錯誤處理方案。 請參閱 錯誤處理方案 了解下層的流式編解碼器可支持的標準錯誤處理方案。errors 參數(shù)將被賦值給一個同名的屬性。 通過對此屬性賦值就可以在
StreamWriter對象的生命期內在不同的錯誤處理策略之間進行切換。-
write(object)? 將編碼后的對象內容寫入到流。
-
reset()? 刷新并重置用于保持狀態(tài)的編解碼器緩沖區(qū)。
調用此方法應當確保在干凈的狀態(tài)下放入輸出數(shù)據(jù),以允許直接添加新的干凈數(shù)據(jù)而無須重新掃描整個流來恢復狀態(tài)。
-
除了上述的方法,StreamWriter 還必須繼承來自下層流的所有其他方法和屬性。
StreamReader 對象?
StreamReader 類是 Codec 的子類,它定義了以下方法,每個流式讀取器都必須定義這些方法以便與 Python 編解碼器注冊表相兼容。
-
class
codecs.StreamReader(stream, errors='strict')? StreamReader實例的構造器。所有流式讀取器必須提供此構造器接口。 它們可以自由地添加額外的關鍵字參數(shù),但只有在這里定義的參數(shù)才會被 Python 編解碼器注冊表所使用。
stream 參數(shù)必須為一個基于特定編解碼器打開用于讀取文本或二進制數(shù)據(jù)的文件類對象。
StreamReader可以通過提供 errors 關鍵字參數(shù)來實現(xiàn)不同的錯誤處理方案。 請參閱 錯誤處理方案 了解下層的流式編解碼器可支持的標準錯誤處理方案。errors 參數(shù)將被賦值給一個同名的屬性。 通過對此屬性賦值就可以在
StreamReader對象的生命期內在不同的錯誤處理策略之間進行切換。errors 參數(shù)所允許的值集合可以使用
register_error()來擴展。-
read([size[, chars[, firstline]]])? 解碼來自流的數(shù)據(jù)并返回結果對象。
chars 參數(shù)指明要返回的解碼后碼位或字節(jié)數(shù)量。
read()方法絕不會返回超出請求數(shù)量的數(shù)據(jù),但如果可用數(shù)量不足,它可能返回少于請求數(shù)量的數(shù)據(jù)。size 參數(shù)指明要讀取并解碼的已編碼字節(jié)或碼位的最大數(shù)量近似值。 解碼器可以適當?shù)匦薷拇嗽O置。 默認值 -1 表示盡可能多地讀取并解碼。 此形參的目的是防止一次性解碼過于巨大的文件。
firstline 旗標指明如果在后續(xù)行發(fā)生解碼錯誤,則僅返回第一行就足夠了。
此方法應當使用“貪婪”讀取策略,這意味著它應當在編碼格式定義和給定大小所允許的情況下盡可能多地讀取數(shù)據(jù),例如,如果在流上存在可選的編碼結束或狀態(tài)標記,這些內容也應當被讀取。
-
readline([size[, keepends]])? 從輸入流讀取一行并返回解碼后的數(shù)據(jù)。
如果給定了 size,則將其作為 size 參數(shù)傳遞給流的
read()方法。如果 keepends 為假值,則行結束符將從返回的行中去除。
-
readlines([sizehint[, keepends]])? 從輸入流讀取所有行并將其作為一個行列表返回。
行結束符會使用編解碼器的
decode()方法來實現(xiàn),并且如果 keepends 為真值則會將其包含在列表條目中。如果給定了 sizehint,則將其作為 size 參數(shù)傳遞給流的
read()方法。
-
reset()? 重置用于保持狀態(tài)的編解碼器緩沖區(qū)。
請注意不應當對流進行重定位。 使用此方法的主要目的是為了能夠從解碼錯誤中恢復。
-
除了上述的方法,StreamReader 還必須繼承來自下層流的所有其他方法和屬性。
StreamReaderWriter 對象?
StreamReaderWriter 是一個方便的類,允許對同時工作于讀取和寫入模式的流進行包裝。
其設計使得開發(fā)者可以使用 lookup() 函數(shù)所返回的工廠函數(shù)來構造實例。
-
class
codecs.StreamReaderWriter(stream, Reader, Writer, errors='strict')? 創(chuàng)建一個
StreamReaderWriter實例。 stream 必須為一個文件類對象。 Reader 和 Writer 必須為分別提供了StreamReader和StreamWriter接口的工廠函數(shù)或類。 錯誤處理通過與流式讀取器和寫入器所定義的相同方式來完成。
StreamReaderWriter 實例定義了 StreamReader 和 StreamWriter 類的組合接口。 它們還繼承了來自下層流的所有其他方法和屬性。
StreamRecoder 對象?
StreamRecoder 將數(shù)據(jù)從一種編碼格式轉換為另一種,這對于處理不同編碼環(huán)境的情況有時會很有用。
其設計使得開發(fā)者可以使用 lookup() 函數(shù)所返回的工廠函數(shù)來構造實例。
-
class
codecs.StreamRecoder(stream, encode, decode, Reader, Writer, errors='strict')? 創(chuàng)建一個實現(xiàn)了雙向轉換的
StreamRecoder實例: encode 和 decode 工作于前端 — 對代碼可見的數(shù)據(jù)調用read()和write(),而 Reader 和 Writer 工作于后端 — stream 中的數(shù)據(jù)。你可以使用這些對象來進行透明轉碼,例如從 Latin-1 轉為 UTF-8 以及反向轉換。
stream 參數(shù)必須為一個文件類對象。
encode 和 decode 參數(shù)必須遵循
Codec接口。 Reader 和 Writer 必須為分別提供了StreamReader和StreamWriter接口對象的工廠函數(shù)或類。錯誤處理通過與流式讀取器和寫入器所定義的相同方式來完成。
StreamRecoder 實例定義了 StreamReader 和 StreamWriter 類的組合接口。 它們還繼承了來自下層流的所有其他方法和屬性。
編碼格式與 Unicode?
字符串在系統(tǒng)內部存儲為 0x0--0x10FFFF 范圍內的碼位序列。 (請參閱 PEP 393 了解有關實現(xiàn)的詳情。) 一旦字符串對象要在 CPU 和內存以外使用,字節(jié)的大小端順序和字節(jié)數(shù)組的存儲方式就成為一個關鍵問題。 如同使用其他編解碼器一樣,將字符串序列化為字節(jié)序列被稱為 編碼,而從字節(jié)序列重建字符串被稱為 解碼。 存在許多不同的文本序列化編解碼器,它們被統(tǒng)稱為 文本編碼。
最簡單的文本編碼格式 (稱為 'latin-1' 或 'iso-8859-1') 將碼位 0--255 映射為字節(jié)值 0x0--0xff,這意味著包含 U+00FF 以上碼位的字符串對象無法使用此編解碼器進行編碼。 這樣做將引發(fā) UnicodeEncodeError,其形式類似下面這樣(不過詳細的錯誤信息可能會有所不同): UnicodeEncodeError: 'latin-1' codec can't encode character '\u1234' in position 3: ordinal not in range(256)。
還有另外一組編碼格式(所謂的字符映射編碼)會選擇全部 Unicode 碼位的不同子集并設定如何將這些碼位映射為字節(jié)值 0x0--0xff。 要查看這是如何實現(xiàn)的,只需簡單地打開相應源碼例如 encodings/cp1252.py (這是一個主要在 Windows 上使用的編碼格式)。 其中會有一個包含 256 個字符的字符串常量,指明每個字符所映射的字節(jié)值。
所有這些編碼格式只能對 Unicode 所定義的 1114112 個碼位中的 256 個進行編碼。 一種能夠存儲每個 Unicode 碼位的簡單而直接的辦法就是將每個碼位存儲為四個連續(xù)的字節(jié)。 存在兩種不同的可能性:以大端序存儲或以小端序存儲。 這兩種編碼格式分別被稱為 UTF-32-BE 和 UTF-32-LE。 它們的缺點可以舉例說明:如果你在一臺小端序的機器上使用 UTF-32-BE 則你將必須在編碼和解碼時翻轉字節(jié)。 UTF-32 避免了這個問題:字節(jié)的排列將總是使用自然順序。 當這些字節(jié)被具有不同字節(jié)順序的 CPU 讀取時,則必須進行字節(jié)翻轉。 為了能夠檢測 UTF-16 或 UTF-32 字節(jié)序列的大小端序,可以使用所謂的 BOM ("字節(jié)順序標記")。 這對應于 Unicode 字符 U+FEFF。 此字符可添加到每個 UTF-16 或 UTF-32 字節(jié)序列的開頭。 此字符的字節(jié)翻轉版本 (0xFFFE) 是一個不可出現(xiàn)于 Unicode 文本中的非法字符。 因此當發(fā)現(xiàn)一個 UTF-16 或 UTF-32 字節(jié)序列的首個字符是 U+FFFE 時,就必須在解碼時進行字節(jié)翻轉。 不幸的是字符 U+FEFF 還有第二個含義 ZERO WIDTH NO-BREAK SPACE: 即寬度為零并且不允許用來拆分單詞的字符。 它可以被用來為語言分析算法提供提示。 在 Unicode 4.0 中用 U+FEFF 表示 ZERO WIDTH NO-BREAK SPACE 已被棄用(改用 U+2060 (WORD JOINER) 負責此任務)。 然而 Unicode 軟件仍然必須能夠處理 U+FEFF 的兩個含義:作為 BOM 它被用來確定已編碼字節(jié)的存儲布局,并在字節(jié)序列被解碼為字符串后將其去除;作為 ZERO WIDTH NO-BREAK SPACE 它是一個普通字符,將像其他字符一樣被解碼。
還有另一種編碼格式能夠對所有的 Unicode 字符進行編碼:UTF-8。 UTF-8 是一種 8 位編碼,這意味著在 UTF-8 中沒有字節(jié)順序問題。 UTF-8 字節(jié)序列中的每個字節(jié)由兩部分組成:標志位(最重要的位)和內容位。 標志位是由零至四個值為 1 的二進制位加一個值為 0 的二進制位構成的序列。 Unicode 字符會按以下形式進行編碼(其中 x 為內容位,當拼接為一體時將給出對應的 Unicode 字符):
范圍 |
編碼 |
|---|---|
|
0xxxxxxx |
|
110xxxxx 10xxxxxx |
|
1110xxxx 10xxxxxx 10xxxxxx |
|
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
Unicode 字符最不重要的一個位就是最右側的二進制位 x。
由于 UTF-8 是一種 8 位編碼格式,因此 BOM 是不必要的,并且已編碼字符串中的任何 U+FEFF 字符(即使是作為第一個字符)都會被視為是 ZERO WIDTH NO-BREAK SPACE。
在沒有外部信息的情況下,就不可能毫無疑義地確定一個字符串使用了何種編碼格式。 每種字符映射編碼格式都可以解碼任意的隨機字節(jié)序列。 然而對 UTF-8 來說這卻是不可能的,因為 UTF-8 字節(jié)序列具有不允許任意字節(jié)序列的特別結構。 為了提升 UTF-8 編碼檢測的可靠性,Microsoft 發(fā)明了一種 UTF-8 變體形式 (Python 2.5 稱之為 "utf-8-sig") 專門用于其 Notepad 程序:在任何 Unicode 字符在被寫入文件之前,會先寫入一個 UTF-8 編碼的 BOM (它看起來是這樣一個字節(jié)序列: 0xef, 0xbb, 0xbf)。 由于任何字符映射編碼后的文件都不大可能以這些字節(jié)值開頭(例如它們會映射為
LATIN SMALL LETTER I WITH DIAERESISRIGHT-POINTING DOUBLE ANGLE QUOTATION MARKINVERTED QUESTION MARK
對于 iso-8859-1 編碼格式來說),這提升了根據(jù)字節(jié)序列來正確猜測 utf-8-sig 編碼格式的成功率。 所以在這里 BOM 的作用并不是幫助確定生成字節(jié)序列所使用的字節(jié)順序,而是作為幫助猜測編碼格式的記號。 在進行編碼時 utf-8-sig 編解碼器將把 0xef, 0xbb, 0xbf 作為頭三個字節(jié)寫入文件。 在進行解碼時 utf-8-sig 將跳過這三個字節(jié),如果它們作為文件的頭三個字節(jié)出現(xiàn)的話。 在 UTF-8 中并不推薦使用 BOM,通常應當避免它們的出現(xiàn)。
標準編碼?
Python 自帶了許多內置的編解碼器,它們的實現(xiàn)或者是通過 C 函數(shù),或者是通過映射表。 以下表格是按名稱排序的編解碼器列表,并提供了一些常見別名以及編碼格式通常針對的語言。 別名和語言列表都不是詳盡無遺的。 請注意僅有大小寫區(qū)別或使用連字符替代下劃線的拼寫形式也都是有效的別名;因此,'utf-8' 是 'utf_8' 編解碼器的有效別名。
CPython implementation detail: 有些常見編碼格式可以繞過編解碼器查找機制來提升性能。 這些優(yōu)化機會對于 CPython 來說僅能通過一組有限的別名(大小寫不敏感)來識別:utf-8, utf8, latin-1, latin1, iso-8859-1, iso8859-1, mbcs (Windows 專屬), ascii, us-ascii, utf-16, utf16, utf-32, utf32, 也包括使用下劃線替代連字符的的形式。 使用這些編碼格式的其他別名可能會導致更慢的執(zhí)行速度。
在 3.6 版更改: 可識別針對 us-ascii 的優(yōu)化機會。
許多字符集都支持相同的語言。 它們在個別字符(例如是否支持 EURO SIGN 等)以及給字符所分配的碼位方面存在差異。 特別是對于歐洲語言來說,通常存在以下幾種變體:
某個 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 |
日語 |
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 |
越南語 |
cp65001 |
僅Windows: Windows UTF-8 ( 3.3 新版功能. |
|
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 |
統(tǒng)一漢語 |
gb18030 |
gb18030-2000 |
統(tǒng)一漢語 |
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_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 |
所有語言 |
utf_8_sig |
所有語言 |
在 3.4 版更改: utf-16* and utf-32* 編碼器將不再允許編碼代理碼位 (U+D800--U+DFFF)。 utf-32* 解碼器將不再解碼與代理碼位相對應的字節(jié)序列。
Python 專屬的編碼格式?
有一些預定義編解碼器是 Python 專屬的,因此它們在 Python 之外沒有意義。 這些編解碼器按其所預期的輸入和輸出類型在下表中列出(請注意雖然文本編碼是編解碼器最常見的使用場景,但下層的編解碼器架構支持任意數(shù)據(jù)轉換而不僅是文本編碼)。 對于非對稱編解碼器,該列描述的含義是編碼方向。
文字編碼?
以下編解碼器提供了 str 到 bytes 的編碼和 bytes-like object 到 str 的解碼,類似于 Unicode 文本編碼。
編碼 |
別名 |
含義 |
|---|---|---|
idna |
實現(xiàn) RFC 3490,另請參閱 |
|
mbcs |
ansi, dbcs |
Windows 專屬:根據(jù) ANSI 代碼頁(CP_ACP)對操作數(shù)進行編碼。 |
oem |
Windows 專屬:根據(jù) OEM 代碼頁(CP_OEMCP)對操作數(shù)進行編碼。 3.6 新版功能. |
|
palmos |
PalmOS 3.5 的編碼格式 |
|
punycode |
實現(xiàn) RFC 3492。 不支持有狀態(tài)編解碼器。 |
|
raw_unicode_escape |
Latin-1 編碼格式附帶對其他碼位以 |
|
undefined |
所有轉換都將引發(fā)異常,甚至對空字符串也不例外。 錯誤處理方案會被忽略。 |
|
unicode_escape |
適合用于以 ASCII 編碼的 Python 源代碼中的 Unicode 字面值內容的編碼格式,但引號不會被轉義。 對 Latin-1 源代碼進行解碼。 請注意 Python 源代碼實際上默認使用 UTF-8。 |
|
unicode_internal |
返回操作數(shù)的內部表示。 不支持有狀態(tài)的編解碼器。 3.3 版后已移除: 此表示已被 PEP 393 所廢棄。 |
二進制轉換?
以下編解碼器提供了二進制轉換: bytes-like object 到 bytes 的映射。 它們不被 bytes.decode() 所支持(該方法只生成 str 類型的輸出)。
編碼 |
別名 |
含義 |
編碼器/解碼器 |
|---|---|---|---|
base64_codec 1 |
base64, base_64 |
將操作數(shù)轉換為多行 MIME base64 (結果總是包含一個末尾的 在 3.4 版更改: 接受任意 bytes-like object 作為輸入用于編碼和解碼 |
|
bz2_codec |
bz2 |
使用bz2壓縮操作數(shù) |
|
hex_codec |
hex |
將操作數(shù)轉換為十六進制表示,每個字節(jié)有兩位數(shù) |
|
quopri_codec |
quopri, quotedprintable, quoted_printable |
將操作數(shù)轉換為 MIME 帶引號的可打印數(shù)據(jù) |
|
uu_codec |
uu |
使用uuencode轉換操作數(shù) |
|
zlib_codec |
zip, zlib |
使用gzip壓縮操作數(shù) |
- 1
除了 字節(jié)類對象,
'base64_codec'也接受僅包含 ASCII 的str實例用于解碼
3.2 新版功能: 恢復二進制轉換。
在 3.4 版更改: 恢復二進制轉換的別名。
文字轉換?
以下編解碼器提供了文本轉換: str 到 str 的映射。 它不被 str.encode() 所支持(該方法只生成 bytes 類型的輸出)。
編碼 |
別名 |
含義 |
|---|---|---|
rot_13 |
rot13 |
返回操作數(shù)的凱撒密碼加密結果 |
3.2 新版功能: 恢復 rot_13 文本轉換。
在 3.4 版更改: 恢復 rot13 別名。
encodings.idna --- 應用程序中的國際化域名?
此模塊實現(xiàn)了 RFC 3490 (應用程序中的國際化域名) 和 RFC 3492 (Nameprep: 用于國際化域名 (IDN) 的 Stringprep 配置文件)。 它是在 punycode 編碼格式和 stringprep 的基礎上構建的。
這些 RFC 共同定義了一個在域名中支持非 ASCII 字符的協(xié)議。 一個包含非 ASCII 字符的域名 (例如 www.Alliancefran?aise.nu) 會被轉換為兼容 ASCII 的編碼格式 (簡稱 ACE,例如 www.xn--alliancefranaise-npb.nu)。 隨后此域名的 ACE 形式可以用于所有由于特定協(xié)議而不允許使用任意字符的場合,例如 DNS 查詢,HTTP Host 字段等等。 此轉換是在應用中進行的;如有可能將對用戶可見:應用應當透明地將 Unicode 域名標簽轉換為線上的 IDNA,并在 ACE 標簽被呈現(xiàn)給用戶之前將其轉換回 Unicode。
Python 以多種方式支持這種轉換: idna 編解碼器執(zhí)行 Unicode 和 ACE 之間的轉換,基于在 section 3.1 of RFC 3490 中定義的分隔字符將輸入字符串拆分為標簽,再根據(jù)需要將每個標簽轉換為 ACE,相反地又會基于 . 分隔符將輸入字節(jié)串拆分為標簽,再將找到的任何 ACE 標簽轉換為 Unicode。 此外,socket 模塊可透明地將 Unicode 主機名轉換為 ACE,以便應用在將它們傳給 socket 模塊時無須自行轉換主機名。 除此之外,許多包含以主機名作為函數(shù)參數(shù)的模塊例如 http.client 和 ftplib 都接受 Unicode 主機名(并且 http.client 也會在 Host 字段中透明地發(fā)送 IDNA 主機名,如果它需要發(fā)送該字段的話)。
當從線路接收主機名時(例如反向名稱查找),到 Unicode 的轉換不會自動被執(zhí)行:希望向用戶提供此種主機名的應用應當將它們解碼為 Unicode。
encodings.idna 模塊還實現(xiàn)了 nameprep 過程,該過程會對主機名執(zhí)行特定的規(guī)范化操作,以實現(xiàn)國際域名的大小寫不敏感特性與合并相似的字符。 如果有需要可以直接使用 nameprep 函數(shù)。
-
encodings.idna.nameprep(label)? 返回 label 經過名稱處理操作的版本。 該實現(xiàn)目前基于查詢字符串,因此
AllowUnassigned為真值。
encodings.mbcs --- Windows ANSI代碼頁?
此模塊實現(xiàn)ANSI代碼頁(CP_ACP)。
Availability: 僅Windows可用
在 3.3 版更改: 支持任何錯誤處理
在 3.2 版更改: 在 3.2 版之前, errors 參數(shù)會被忽略;總是會使用 'replace' 進行編碼,并使用 'ignore' 進行解碼。
encodings.utf_8_sig --- 帶BOM簽名的UTF-8編解碼器?
此模塊實現(xiàn)了 UTF-8 編解碼器的一個變種:在編碼時將把 UTF-8 已編碼 BOM 添加到 UTF-8 編碼字節(jié)數(shù)據(jù)的開頭。 對于有狀態(tài)編碼器此操作只執(zhí)行一次(當首次寫入字節(jié)流時)。 在解碼時將跳過數(shù)據(jù)開頭作為可選項的 UTF-8 已編碼 BOM。
