用戶:Xyy23330121/Python/字符串和編碼
本章將學習編碼的相關信息,以及如何用 Python 生成或解決一類常見的文本亂碼。
編碼是計算機存儲信息的方式。
bytes 對象與 bytearray 對象
編輯bytes 對象
編輯bytes 對象是 Python 用於表示二進制數據的對象。我們可以用b
作前綴創建 bytes 對象:
a = b"abc"
此時,引號內的內容只能為 ASCII 編碼中的字符。a
、b
和c
在 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))
。