Python裏的string 和 unicode 區別講得很明白的文章

先要弄清楚的是,在python裏,string object和unicode object是兩種不一樣的類型。python

 原文博主--http://blog.csdn.net/feisan
string object是由characters組成的sequence,而unicode object是Unicode code units組成的sequence。

string裏的character是有多種編碼方式的,好比單字節的ASCII,雙字節的GB2312等等,再好比UTF-8。很明顯要想解讀string,必需知道string裏的character是用哪一種編碼方式,而後才能進行。

Unicode code unit又是什麼東西呢?一個Unicode code unit是一個16-bit或者32-bit的數值,每一個數值表明一個unicode符號。在python裏,16-bit的unicode,對應的是ucs2編碼。32-bit對應的是ucs4編碼。是否是感受string裏character的編碼沒什麼區別?反正我如今腦子裏就是這樣一個印象:在Python裏,ucs2或者ucs4編碼的,咱們叫作unicode object,其餘編碼的咱們就叫作string。

至於python裏的unicode究竟是ucs2仍是ucs4的,能夠在編譯時指定。例如Linux下,要用ucs2作unicode的編碼,能夠這樣
# ./configure --enable-unicode=ucs2 
# make
# make install
下載的Windows預編譯版本,通常都是ucs2的。要想知道某個python運行環境是ucs2仍是ucs4,能夠查看sys.maxunicde,65535就是ucs2的,另外一個很大的數值就是ucs4。

下面咱們看看string和unicode在python裏的不一樣
咱們先看看在簡體中文Windows 2003系統下,系統編碼是GBK
>>> a = '你好'
>>> a
'/xc4/xe3/xba/xc3'
>>> b = u'你好'
>>> b
u'/u4f60/u597d'
>>> print a
你好
>>> print b
你好
>>> a.__class__
<type 'str'>
>>> b.__class__
<type 'unicode'>
>>> len(a)
4
>>> len(b)
2

在一個系統編碼爲UTF-8的Linux環境下
>>> a = '你好'
>>> a
'/xe4/xbd/xa0/xe5/xa5/xbd'
>>> b = u'你好'
>>> b
u'/u4f60/u597d'
>>> print a
你好
>>> print b
你好
>>> a.__class__
<type 'str'>
>>> b.__class__
<type 'unicode'>
>>> len(a)
6
>>> len(b)
2

如何?簡單總結一下:
一、string直接用引號來表示,unicode在引號前加一個u
二、直接輸入的string常量會用系統缺省編碼方式來編碼,例如在GBK環境下,'你好'會編碼成'/xc4/xe3/xba/xc3',而在UTF-8環境下就成了'/xe4/xbd/xa0/xe5/xa5/xbd'。
三、len(string)返回string的字節數,len(unicode)返回的是字符數
四、很重要的一點,print unicode不會亂碼。如今咱們經常使用的Linux、Windows系統,都是支持unicode的,版本太老的不算。好比Windows 2003支持ucs2,因此在中文Windows2003下,除了能夠正常顯示缺省的GBK編碼外,還能夠正常顯示ucs2編碼。舉個例子,仍是在中文Windows 2003的GBK環境下:
>>>a = '/xe4/xbd/xa0/xe5/xa5/xbd' # UTF-8的'你好'
>>> print a
浣犲ソ
>>> b = unicode(a, "UTF-8")
>>> b
u'/u4f60/u597d'
>>> print b
你好

應該明白了吧?

下面再說說string和unicode的相互轉換,什麼unicode()、decode()、encode()、codecs之類的。函數

繼續。

先說一下,前面提到,print(string)的時候,若是string是按當前環境編碼方式編碼的,能夠正常輸出,不會亂碼;若是string不是當前編碼的,就會亂碼。而print(unicode)是不會亂碼的。why?應爲print(unicode)的時候,會把unicode先轉成當前編碼,而後再輸出。我沒看過print的源碼,不過估計是這樣的。

string轉unicode或者unicode轉string,是很常見的操做。

string和unicode都有decode()和encode()方法。decode是string2unicode,encode天然就是unicode2string。看個例子(中文Windows2003下):
>>> a = '你好'
>>> a
'/xc4/xe3/xba/xc3'
>>> b = u'你好'
>>> c = a.decode('gbk') #gbk string to unicode
>>> b == c
True
>>> c
u'/u4f60/u597d'
>>> d = b.encode('gbk') #unicode to gbk string
>>> d == a
True
>>> d
'/xc4/xe3/xba/xc3'
>>> e = b.encode('utf-8') #unicode to utf-8 string
>>> e
'/xe4/xbd/xa0/xe5/xa5/xbd'

decode或者encode的時候,若是不指定編碼方式,會按照缺省編碼方式來處理。查看、設置缺省編碼方式能夠這樣作:
>>> import sys
>>> sys.getdefaultencoding()
'ascii'
>>> reload(sys) 
<module 'sys' (built-in)>
>>> sys.setdefaultencoding('gbk')
上面調用sys.setdefaultencoding()的時候先reload一下sys module,緣由是python啓動時缺省會import site.py, 而site.py會del sys.setdefaultencoding(),因此須要reload(sys)。具體能夠看看site.py的源碼。

接下來講說unicode()函數。其實unicode函數就是調用string的decode()方法,把string轉成unicode,例如:
>>> a = '你好'
>>> b = unicode(a)
>>> b
u'/u4f60/u597d'
>>> c = a.decode('gbk')
>>> c
u'/u4f60/u597d'
>>> print b, c, b==c
你好 你好 True

下一部分說說codec
ui

最後說說關於codecs。所謂的codec就是編碼器和解碼器(encoder and decoder)的集合。除了各類字符串編碼的codec,還有各類文件格式的codec,好比壓縮、解壓縮的,圖像的,音頻的,等等。咱們這裏說的固然是跟字符串編碼相關的了。

看看代碼
>>> import codecs
>>> gbk=codecs.lookup('gbk')
>>> gbk
<codecs.CodecInfo object for encoding gbk at 0xad3ea0>
>>> gbk.decode("你好")
(u'/u4f60/u597d', 4)
>>> gbk.encode(u'/u4f60/u597d')
('/xc4/xe3/xba/xc3', 2)
編碼

相關文章
相關標籤/搜索