Python 模塊 codecs-字符串編碼和解碼

Python 模塊 codecs-字符串編碼和解碼

模塊 codecs 提供接口轉變數據編碼,它常常和 Unicode 編碼使用,但是也可以和其他編碼一起使用。

Unicode 編碼


Python 解釋器 CPython 3.x 提供了兩種字符串類型: text 和 byte string。bytes 是一個8位的字節序列,str是文本字符串,內部是一個 Unicode code points 序列。code point 值可以是2個或者4個字節,根據編譯 Python 時給定的選項確定,所以說 Unicode 編碼的字節長度是可變的。

當 str 打印時,根據內部的字節編碼類型,把內部的 code point 轉換為顯示的字符,所以 Unicode 的數據需要根據字節編碼轉換為內部顯示的字符。使用字節序列的 bytes 和 code point 是不一樣的,它沒有這種情況。

Unicode 最常用的編碼類型是 UTF-8 和 UTF-16,它使用一個字節或者2個字節的序列表示每個 code point。也包括其他的編碼,由其他語言使用,他們不只使用2個字節表示 code point。

編碼


為了更好的理解編碼類型,下面的例子使用不同的編碼打印了相同的數據。首先定義了一個函數 to_hex() 返回數據的二進制表示。

Python 模塊 codecs-字符串編碼和解碼

執行:

Python 模塊 codecs-字符串編碼和解碼

函數 to_hex() 第一個參數是要打印的二進制數據,第二個參數指定每次打印多少個字節,字節之間按空格分隔。

下面的例子分別使用 utf-8 和 utf-16 編碼同一個字符串,然後打印字節數據。

Python 模塊 codecs-字符串編碼和解碼

執行:

Python 模塊 codecs-字符串編碼和解碼

文件


編碼和解碼對於 IO 操作是非常重要的,讀取和寫入都必須要知道數據的編碼。例如寫入一個文件,Socket或者其他流,數據必須要有正確的編碼。通常從一個字節流轉為內部的字符串表示叫做解碼,把內部數據轉換為特定的字節流叫做編碼。模塊 codecs 提供了方法自動解碼和編碼數據,所以我們寫應用時,常常可以忽略這些細節。

codecs 模塊的 open() 函數可以指定特定的編碼和文件工作。

Python 模塊 codecs-字符串編碼和解碼

執行:

Python 模塊 codecs-字符串編碼和解碼

本例中,使用命令行傳入編碼類型,然後使用 codecs.open() 函數寫入指定編碼的數據,最後打印了不同編碼類型的數據。

字節順序


類似 UTF-8 和 UTF-16 這種多字節的編碼類型,常常在多個計算機之間傳遞數據的時候,需要注意字節順序的問題。因為不同的計算機系統使用的字節順序有可能不一樣。這樣的特性通常稱為 endianness,通常會根據硬件結構,操作系統,應用開發者來決定。

多字節的編碼類型根據字節開頭的 BOM(byte-order marker)來確定字節順序,codecs 定義了多個常量標識不同編碼的 BOM 值。

Python 模塊 codecs-字符串編碼和解碼

執行:

Python 模塊 codecs-字符串編碼和解碼

字節順序會由 codecs 模塊自動確定,你也可以在編碼的時候顯示的指定。下面不使用系統的字節順序,而使用自定義的字節順序寫入數據到文件。

Python 模塊 codecs-字符串編碼和解碼

執行:

Python 模塊 codecs-字符串編碼和解碼

本例中,文件開頭寫入了 bom marker,當讀取文件的時候,文件內容多輸出了 bom marker。要想只返回文件內容,讀取的時候需要指定編碼類型。

Python 模塊 codecs-字符串編碼和解碼

執行:

Python 模塊 codecs-字符串編碼和解碼

當不指定編碼類型時,默認使用系統的內置編碼類型。如果內置編碼類型和文件實際的類型不一致,則觸發異常 UnicodeDecodeError。

Python 模塊 codecs-字符串編碼和解碼

執行:

Python 模塊 codecs-字符串編碼和解碼

錯誤處理


當讀取和寫入文件時,使用正確的編碼類型是至關重要的。如果讀取文件時,指定的編碼類型錯誤,則觸發異常,就和上面遇到的一樣。當使用錯誤的編碼類型,寫入數據到文件時,數據就會丟失。

codecs 提供了下面5種選項處理從字符串編碼和從字節流解碼遇到的問題。

  • strict 如果數據轉換失敗,則觸發異常
  • replace 把不能編碼的數據替換掉
  • ignore 忽略不能編碼的數據
  • xmlcharrefreplace XML 字符
  • backslashreplace 轉義序列

下面的例子,試圖把一個 Unicode 編碼的數據寫入到 ASCII 流的文件中,觸發不同的錯誤處理方式。

Python 模塊 codecs-字符串編碼和解碼

執行:

Python 模塊 codecs-字符串編碼和解碼

正如上面所說,錯誤處理選項使用 strict 觸發異常,replace 替換不能編碼的字符,ignore 忽略。

編碼轉換


雖然大部分程序都使用 str 處理數據,而編碼解碼數據只是 IO 的一部分。有時候也需要轉換編碼格式。EncodedFile() 接收一個字節流和兩個編碼參數,把數據從一個編碼類型轉換為另一個。

Python 模塊 codecs-字符串編碼和解碼

執行:

Python 模塊 codecs-字符串編碼和解碼

本例把 utf-8 編碼類型轉換為 utf-16。


分享到:


相關文章: