Python的字符串編碼


本文用實驗詳細地演示了Python2和Python3在字符串編碼上的區別。

在Python2中,字符串字面量對應於8位的字符或面向字節編碼的字節字面量。這些字符串的一個重要限制是它們無法完全地支持國際字符集和Unicode編碼。為了解決這種限制,Python2對Unicode數據使用了單獨的字符串類型。要輸入Unicode字符串字面量,要在第一個引號前加上前最'u'。

 

Python2中還有一種稱為字節字面量的字符串類型,它是指一個已經編碼的字符串字面量,在Python2中字節字面量和普通字符串沒有差別,因為在Python2中普通字符串實際上就是已經編碼(非Unicode)的字節字符串。

 

在Python3中,不必加入這個前綴字符,否則是語法錯誤,這是因為所有的字符串默認已經是Unicode編碼了。如果使用-U選項運行解釋器,Python2會模擬這種行為(即所有字符串字面量將被作為Unicode字符對待,u前綴可以省略)。在Python3中,字節字面量變成了與普通字符串不同的類型。

 

~/download/firefox $ python2
Python 2.7.2 (default, Jun 29 2011, 11:17:09)
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.

>>> '張俊' #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'張俊'
張俊
>>>

 

 

~/download/firefox $ python3
Python 3.2.2 (default, Sep 5 2011, 04:33:58)
[GCC 4.6.1 20110819 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.


>>> '張俊' #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'))  #必須將字節字符串解碼后才能打印出來
張俊


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM