明白了Unicode和UTF-8的區(qū)別和關(guān)系后,再來看看Python的編碼方式。在Python 3中,字符串的編碼使用str和bytes兩種類型。
(1)str字符串:使用Unicode編碼。
(2)bytes字符串:使用將Unicode轉(zhuǎn)化成的某種類型的編碼,如UTF-8、GBK。
在Python 3中,字符串默認(rèn)的編碼為Unicode,所以基本上出現(xiàn)的問題比較少。而Python 2相對(duì)Python 3來說,由于字符串默認(rèn)使用將Unicode轉(zhuǎn)化成的某種類型的編碼,可以采用的編碼比較多,因此使用過程中經(jīng)常遇到編碼問題,為用戶帶來很多煩惱。
本書使用Python 3作為編程語言,為了讓大家更容易理解,后面僅討論P(yáng)ython 3的中文編碼。
Python的默認(rèn)編碼如下:
In [1]:str1 = "我們" print (str1) print (type(str1))
我們
<class'str'>
可以看出,Python 3的字符串默認(rèn)編碼為str,也就是使用Unicode編碼。
encode和decode
這些默認(rèn)的str字符串怎么轉(zhuǎn)化成bytes字符串呢?
這里就要用到encode和decode了。encode的作用是將Unicode編碼轉(zhuǎn)換成其他編碼的字符串,而decode的作用是將其他編碼的字符串轉(zhuǎn)換成Unicode編碼,如圖10-1所示。
圖10-1 encode與decode編碼的轉(zhuǎn)換
圖10-1所示為Unicode和UTF-8之間編碼轉(zhuǎn)換的例子,代碼實(shí)現(xiàn)如下:
In [2]:str1 = "我們" str_utf8 = str1.encode('utf-8') print (str_utf8) print (type(str_utf8))
b'\xe6\x88\x91\xe4\xbb\xac'
<class'bytes'>
這里的str_utf8已經(jīng)為UTF-8編碼了,中文字符轉(zhuǎn)換后,1個(gè)Unicode字符將變?yōu)?個(gè)UTF-8字符,\xe6就是其中一個(gè)字節(jié),因?yàn)樗闹凳?30,沒有對(duì)應(yīng)的字母可以顯示,所以以十六進(jìn)制顯示字節(jié)的數(shù)值。\xe6\x88\x91三個(gè)字節(jié)代表“我”字,\xe4\xbb\xac三個(gè)字節(jié)代表“們”字,代碼實(shí)現(xiàn)如下:
In [3]:str_decode = str1.encode('utf-8').decode('utf-8') print (str_decode) print (type(str_decode))
我們
<class'str'>
再用decode可以把用UTF-8編碼的字符串解碼為Unicode編碼。要編碼成其他類型的編碼時(shí),也可以用encode,如GBK。如果想要查看具體的編碼類型,那么可以用到chardet,代碼實(shí)現(xiàn)如下:
In [4]:import chardet str_gbk = "我們".encode('gbk') chardet.detect(str_gbk)
{'confidence':0.8095977270813678,
'encoding':'TIS-620'}
如果你腦洞大開,或許會(huì)問這樣一個(gè)問題:Unicode還可以decode嗎?顯示結(jié)果如下:
In [5]:str_unicode_decode = "我們".decode()
------------------------------------------------
AttributeError
Traceback(most recent call last)
<ipython-input-5-0402a0b683b7>
in<module>()
---->1 str_unicode_decode=
"我們".decode()
AttributeError:'str'object has no ttribute'decode'
已經(jīng)被編碼的UTF-8還可以再encode嗎?顯示結(jié)果如下:
In [6]:str_utf8 = "我們".encode('utf-8') str_gbk = str_utf8.encode('gbk')
-----------------------------------------
AttributeError
Traceback(most recent call last)
<ipython-input-6-5d0c32a4bf21>
in<module>()
1 str_utf8="我們".encode('utf-8')
---->2 str_gbk=str_utf8.encode('gbk')
AttributeError:'bytes'object has no attribute'encode'
答案都是否定的。因?yàn)樵赑ython 3中,Unicode不可以再被解碼。如果想把UTF-8轉(zhuǎn)成其他非unicode編碼,那么必須先decode成Unicode,再encode為其他非Unicode編碼,如GBK。
encode轉(zhuǎn)換為其他非Unicode編碼的代碼如下:
In [7]:str_utf8 = "我們".encode('utf-8') str_gbk = str_utf8.decode('utf-8').encode('gbk') print (str_gbk)
b'\xce\xd2\xc3\xc7'
聯(lián)系客服