Python2和Python3在字符串編碼上是有明顯的區別。
在Python2中,字符串無法完全地支持國際字符集和Unicode編碼。為了解決這種限制,Python2對Unicode數據使用了單獨的字符串類型。要輸入Unicode字符串字面量,要在第一個引號前加上'u'。Python2中普通字符串實際上就是已經編碼(非Unicode)的字節字符串。
在Python3中,不必加入這個前綴字符,否則是語法錯誤,這是因為所有的字符串默認已經是Unicode編碼了。
$ python2實例:
>>> '張三' #python2 會自動將字符串轉換為合適編碼的字節字符串
'\xe5\xbc\xa0\xe4\xbf\x8a' #自動轉換為utf-8編碼的字節字符串
>>> u'張三' #顯式指定字符串類型為unicode類型, 此類型字符串沒有編碼,保存的是字符在unicode字符集中的代碼序號
u'\u5f20\u4fca'
>>> '張三'.encode('utf-8') #python2 已經自動將其轉化為utf-8類型編碼,因此再次編碼(python2會將該字符串當作用ascii或unicode編碼過)會出現錯誤。
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 0: ordinal not in range(128)
>>> '張三'.decode('utf-8') #python2 可以正常解碼,返回的字符串類是無編碼的unicode類型
u'\u5f20\u4fca'
>>> b'張三' # ‘張三' 已被python2轉換為utf-8編碼,因此已為字節字符串
'\xe5\xbc\xa0\xe4\xbf\x8a'
>>> print '張三'
張三
>>> print u'張三'
張三
>>> print b'張三'
張三
$ python3實例:
>>> '張三' #python3的字符串默認為unicode格式(無編碼)
'張三'
>>> u'張三' #由於默認為unicode格式,因此字符串不用像python2一樣顯式地指出其類型,否則是語法錯誤。
File "<stdin>", line 1
u'張三'
^
SyntaxError: invalid syntax
>>> type('張三') #python3中文本字符串和字節字符串是嚴格區分的,默認為unicode格式的文本字符串
<class 'str'>
>>> '張三'.decode('utf-8') #因為默認的文本字符串為unicode格式,因此文本字符串沒有decode方法
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'decode'
>>> '張三'.encode('utf-8') #將文本字符串編碼,轉換為已編碼的字節字符串類型
b'\xe5\xbc\xa0\xe4\xbf\x8a'
>>> type('張三'.encode('utf-8'))
<class 'bytes'>
>>> print ('張三'.encode('utf-8')) #對於已編碼的字節字符串,文本字符串的許多特性和方法已經不能使用。
b'\xe5\xbc\xa0\xe4\xbf\x8a'
>>>print ('張三'.encode('utf-8'))
b'\xe5\xbc\xa0\xe4\xbf\x8a'
>>> print ('張三'.encode('utf-8').decode('utf-8')) #必須將字節字符串解碼后才能打印出來
張三