跳至內容

用戶:Xyy23330121/Python/字符串和編碼

來自維基學院

本章將學習編碼的相關信息,以及如何用 Python 生成或解決一類常見的文本亂碼。

編碼是計算機存儲信息的方式。

bytes 對象與 bytearray 對象

[編輯 | 編輯原始碼]

bytes 對象

[編輯 | 編輯原始碼]

bytes 對象是 Python 用於表示二進制數據的對象。我們可以用b作前綴創建 bytes 對象:

a = b"abc"

此時,引號內的內容只能為 ASCII 編碼中的字符。abc在 ASCII 編碼中分別對應十六進制的61、62和63。所以上述例子中創建的對象,它所存儲的二進制數據,用十六進制表示為 616263

由於 ASCII 編碼僅有 127 個字符。因此,二進制每 8 位中,任何超出 127(即二進制的 01111111 ,或十六進制 7F )的二進制數值都需要通過轉義字符來輸入。比如:

a = b"\xf1"

上述例子中創建的對象,所存儲的二進制數據,用十六進制表示為 f1

以上創建 bytes 對象的方法,也是用print函數輸出時的輸出方式。有以下示例:

a = b"a\xf1b"
print(a) #输出:b'a\xf1b'

bytes 對象支持一切不可變序列的操作。雖然 bytes 的創建和表示方法是基於 ASCII 字符的,但比起 ASCII 字符構成的字符串,bytes 對象更像是 0~255 之間整數構成的元組。如果對 bytes 對象用整數索引,會返回一個整數,而非像字符串一樣返回子字符串。

bytearray 對象

[編輯 | 編輯原始碼]

上面提到過,bytes 對象的表現類似由 0~255 之間整數組成的不可變序列。而 bytearray 對象類似由 0~255 之間整數組成的可變序列。bytearray 支持一切可變序列的操作。

bytes 函數與 bytearray 函數

[編輯 | 編輯原始碼]

類似 int 函數,我們可以用 bytes([source])bytearray([source]) 創建 bytes 對象或 bytearray 對象。

其中,參數 source 可以為整數、由 0~255 之間整數組成的可迭代對象。特別的,bytes 對象和 bytearray 對象也是由 0~255 之間整數組成的可迭代對象。

  • 如果 source 為整數,則生成一個包含 source 個字節的對應實例。
  • 如果 source 為由0~255之間整數組成的可迭代對象,則將可迭代對象中的整數原封不動複製到對應位置。

十六進制字符串與 bytes 和 bytearray

[編輯 | 編輯原始碼]

bytes.fromhex 方法和 bytearray.fromhex 方法可以用表示十六進制數字的字符串創建 bytes 對象,創建時字符串不區分大小寫,並且會忽略空格。比如:

value = bytes.fromhex("81f0 EA61")
print(value)   #输出:b'\x81\xf0\xeaa'

代碼的輸出說明,該 bytes 對象所存儲的二進制數據,用十六進制表示為 81F0EA61

類似,我們還可以用 bytes.hex([sep[, bytes_per_sep]])bytearray.hex([sep[, bytes_per_sep]]) 方法創建十六進制字符串。

其中,sep 代表分隔符,默認為空字符串,即不插入分隔符。而 bytes_per_sep 代表插入分隔符的頻率,默認為 1 ,即「每一個字節都插入一個分隔符」。我們有以下示例:

value = bytes.fromhex("81f0 EA61")
print(value.hex())      #输出:81f0ea61
print(value.hex(" "))   #输出:81 f0 ea 61
print(value.hex(" ",2)) #输出:81f0 ea61

bytes 和 bytearray 的方法

[編輯 | 編輯原始碼]

bytes 和 bytearray 有類似字符串的方法。參見:U:Xyy23330121/Python/bytes 和 bytearray 的方法

bytes 對象和字符的編碼

[編輯 | 編輯原始碼]
常用編碼列表
編碼名 適用語言
utf-8 所有語言
ascii 英語
big5 中文(繁體)
gbk 中文
shift-jis 日語
utf-16 所有語言
utf-16-be 所有語言
utf-16-le 所有語言
utf-32 所有語言
utf-32-be 所有語言
utf-32-le 所有語言

字符編碼 是將字符轉化成二進制數據的標準。比如 & 字符,它在 ASCII 編碼方式下,對應的二進制數據是 00100110 。計算機可以通過讀取二進制數據,來還原出對應的字符串。常見的編碼方式有 UTF-8、ASCII、UTF-16、GBK 等。

利用以下方法,我們可以把字符按編碼轉化成對應的bytes對象,也可以把bytes對象按編碼轉化成對應的字符對象。

str.encode(encoding='utf-8', errors='strict')
bytes.decode(encoding='utf-8', errors='strict')

其中,encoding表示要使用的編碼,此處不區分大小寫,也不區分_-。而errors表示出錯時的處理方法。右表列出了幾種常用編碼。如果要查閱所有可用的編碼名稱,可以參照上面列出的文檔。

以下列出幾種常用的錯誤處理方法。如果要查閱所有可用的方法,可以參照上面列出的「錯誤處理方式列表」文檔。

名稱 說明
strict 嚴格模式,遇到無法解碼的碼位或無法編碼的字符,會報錯 ValueError 。
ignore 忽略錯誤。對於無法解碼的碼位或無法編碼的字符,會直接跳過。
replace 在編碼時,遇到無法編碼的字符,就用字符 ? 代替;
在解碼時,遇到無法解碼的字節,就用字符 (U+FFFD)代替。

示例:常見亂碼的解決

[編輯 | 編輯原始碼]

現在絕大多數計算機,在信息處理時,都默認使用了 UTF-8 等常見的編碼方式。但日本的計算機不一樣,一些計算機有概率在處理信息時依舊使用 Shift-JIS 編碼。中文計算機在解壓zip壓縮文件、查閱文本文檔時,如果判斷文件名或文本不是 UTF-8 編碼,就會自動採用 GBK 編碼來解碼文件。用 Shift-JIS 編碼的信息被用 GBK 解碼就會導致亂碼。

要解決這個問題,只需要結合上面的兩個操作即可。我們用以下方式解決它:

error_str = "傕傕偄傠僇儖僥僢僩 搷壺"
print(error_str.encode("GBK").decode(encoding="Shift-JIS",errors="ignore"))

從字符串創建 bytes 或 bytearray

[編輯 | 編輯原始碼]

我們上面提到過 bytes 函數和 bytearray 函數。這兩個函數的完整語法為:

bytes([source[, encoding[, errors]]])

bytearray([source[, encoding[, errors]]])

只有當 source 為字符串時,encoding 參數和 errors 參數才有作用,此時 bytes(source, encoding, errors) 等同於 source.encode(encoding, errors),而 bytearray(source, encoding, errors) 等同於 bytearray(source.encode(encoding, errors))