Python 3的bytes/str之別

veldts發表於2012-02-26

原文:The bytes/str dichotomy in Python 3

Python 3最重要的新特性大概要算是對文字和二進位制資料作了更為清晰的區分。文字總是Unicode,由str型別表示,二進位制資料則由bytes型別表示。Python 3不會以任意隱式的方式混用str和bytes,正是這使得兩者的區分特別清晰。你不能拼接字串和位元組包,也無法在位元組包裡搜尋字串(反之亦然),也不能將字串傳入引數為位元組包的函式(反之亦然)。這是件好事

不管怎樣,字串和位元組包之間的界線是必然的,下面的圖解非常重要,務請牢記於心:

enter image description here

字串可以編碼成位元組包,而位元組包可以解碼成字串。

>>> '€20'.encode('utf-8')
b'\xe2\x82\xac20'
>>> b'\xe2\x82\xac20'.decode('utf-8')
'€20'

這個問題要這麼來看:字串是文字的抽象表示。字串由字元組成,字元則是與任何特定二進位制表示無關的抽象實體。在操作字串時,我們生活在幸福的無知之中。我們可以對字串進行分割和分片,可以拼接和搜尋字串。我們並不關心它們內部是怎麼表示的,字串裡的每個字元要用幾個位元組儲存。只有在將字串編碼成位元組包(例如,為了在通道上傳送它們)或從位元組包解碼字串(反向操作)時,我們才會開始關注這點。

傳入encode和decode的引數是編碼(或codec)。編碼是一種用二進位制資料表示抽象字元的方式。目前有很多種編碼。上面給出的UTF-8是其中一種,下面是另一種:

>>> '€20'.encode('iso-8859-15')
b'\xa420'
>>> b'\xa420'.decode('iso-8859-15')
'€20'

編碼是這個轉換過程中至關重要的一部分。離了編碼,bytes物件b'\xa420'只是一堆位元位而已。編碼賦予其含義。採用不同的編碼,這堆位元位的含義就會大不同:

>>> b'\xa420'.decode('windows-1255')
'₪20'

據說百分之八十的金錢損失皆因使用錯誤的編碼導致,因此務必小心謹慎。


引申閱讀

  1. 阿呆學Unicode——編碼

相關文章