模塊 codecs 提供接口轉(zhuǎn)變數(shù)據(jù)編碼,它常常和 Unicode 編碼使用,但是也可以和其他編碼一起使用。
Unicode 編碼
Python 解釋器 CPython 3.x 提供了兩種字符串類型: text 和 byte string。bytes 是一個8位的字節(jié)序列,str是文本字符串,內(nèi)部是一個 Unicode code points 序列。code point 值可以是2個或者4個字節(jié),根據(jù)編譯 Python 時給定的選項確定,所以說 Unicode 編碼的字節(jié)長度是可變的。
當 str 打印時,根據(jù)內(nèi)部的字節(jié)編碼類型,把內(nèi)部的 code point 轉(zhuǎn)換為顯示的字符,所以 Unicode 的數(shù)據(jù)需要根據(jù)字節(jié)編碼轉(zhuǎn)換為內(nèi)部顯示的字符。使用字節(jié)序列的 bytes 和 code point 是不一樣的,它沒有這種情況。
Unicode 最常用的編碼類型是 UTF-8 和 UTF-16,它使用一個字節(jié)或者2個字節(jié)的序列表示每個 code point。也包括其他的編碼,由其他語言使用,他們不只使用2個字節(jié)表示 code point。
編碼
為了更好的理解編碼類型,下面的例子使用不同的編碼打印了相同的數(shù)據(jù)。首先定義了一個函數(shù) to_hex() 返回數(shù)據(jù)的二進制表示。
執(zhí)行:
函數(shù) to_hex() 第一個參數(shù)是要打印的二進制數(shù)據(jù),第二個參數(shù)指定每次打印多少個字節(jié),字節(jié)之間按空格分隔。
下面的例子分別使用 utf-8 和 utf-16 編碼同一個字符串,然后打印字節(jié)數(shù)據(jù)。
執(zhí)行:
文件
編碼和解碼對于 IO 操作是非常重要的,讀取和寫入都必須要知道數(shù)據(jù)的編碼。例如寫入一個文件,Socket或者其他流,數(shù)據(jù)必須要有正確的編碼。通常從一個字節(jié)流轉(zhuǎn)為內(nèi)部的字符串表示叫做解碼,把內(nèi)部數(shù)據(jù)轉(zhuǎn)換為特定的字節(jié)流叫做編碼。模塊 codecs 提供了方法自動解碼和編碼數(shù)據(jù),所以我們寫應用時,常常可以忽略這些細節(jié)。
codecs 模塊的 open() 函數(shù)可以指定特定的編碼和文件工作。
執(zhí)行:
本例中,使用命令行傳入編碼類型,然后使用 codecs.open() 函數(shù)寫入指定編碼的數(shù)據(jù),最后打印了不同編碼類型的數(shù)據(jù)。
字節(jié)順序
類似 UTF-8 和 UTF-16 這種多字節(jié)的編碼類型,常常在多個計算機之間傳遞數(shù)據(jù)的時候,需要注意字節(jié)順序的問題。因為不同的計算機系統(tǒng)使用的字節(jié)順序有可能不一樣。這樣的特性通常稱為 endianness,通常會根據(jù)硬件結(jié)構(gòu),操作系統(tǒng),應用開發(fā)者來決定。
多字節(jié)的編碼類型根據(jù)字節(jié)開頭的 BOM(byte-order marker)來確定字節(jié)順序,codecs 定義了多個常量標識不同編碼的 BOM 值。
執(zhí)行:
字節(jié)順序會由 codecs 模塊自動確定,你也可以在編碼的時候顯示的指定。下面不使用系統(tǒng)的字節(jié)順序,而使用自定義的字節(jié)順序?qū)懭霐?shù)據(jù)到文件。
執(zhí)行:
本例中,文件開頭寫入了 bom marker,當讀取文件的時候,文件內(nèi)容多輸出了 bom marker。要想只返回文件內(nèi)容,讀取的時候需要指定編碼類型。
執(zhí)行:
當不指定編碼類型時,默認使用系統(tǒng)的內(nèi)置編碼類型。如果內(nèi)置編碼類型和文件實際的類型不一致,則觸發(fā)異常 UnicodeDecodeError。
執(zhí)行:
錯誤處理
當讀取和寫入文件時,使用正確的編碼類型是至關重要的。如果讀取文件時,指定的編碼類型錯誤,則觸發(fā)異常,就和上面遇到的一樣。當使用錯誤的編碼類型,寫入數(shù)據(jù)到文件時,數(shù)據(jù)就會丟失。
codecs 提供了下面5種選項處理從字符串編碼和從字節(jié)流解碼遇到的問題。
下面的例子,試圖把一個 Unicode 編碼的數(shù)據(jù)寫入到 ASCII 流的文件中,觸發(fā)不同的錯誤處理方式。
執(zhí)行:
正如上面所說,錯誤處理選項使用 strict 觸發(fā)異常,replace 替換不能編碼的字符,ignore 忽略。
編碼轉(zhuǎn)換
雖然大部分程序都使用 str 處理數(shù)據(jù),而編碼解碼數(shù)據(jù)只是 IO 的一部分。有時候也需要轉(zhuǎn)換編碼格式。EncodedFile() 接收一個字節(jié)流和兩個編碼參數(shù),把數(shù)據(jù)從一個編碼類型轉(zhuǎn)換為另一個。
執(zhí)行:
本例把 utf-8 編碼類型轉(zhuǎn)換為 utf-16。
聯(lián)系客服