python 中的unicode詳解


 

 

通過例子來看問題是比較容易懂的。

首先來看,下面這個是我新建的一個txt文件,名字叫做ivan_utf8.txt,然后里面隨便編輯了一些東西。 

 

 

然后來用控制台打開這個文件,同樣也是截圖:

 

這里就是簡單的打開文本,讀取文本內容,打印出來看,我們看到print出來的是和我寫進去的是一樣的東西。然后呢,我在對這個內容使用decode(‘gbk’),就是解編碼,使用gbk方式進行解碼,什么意思呢?就是說,我假設這個a是gbk方式的編碼,結果是什么呢?大家都看到了,報錯了哈!!!!說明這個不是gbk編碼,是的,我的編碼是utf-8編碼,當然要報錯啦。。。其實主要是這個里面的中文無法識別,如果只有英文應該還是不會報錯的,雖然解出來內容是變樣了哈。。。

 

 

回到我們這個問題,這個報錯是什么意思呢?

 

這就是牽扯到我們今天要講的問題了,看完我講完的內容就能夠知道是為什么了。。。

 

1.python字符串的本質是什么呢?

2.unicode的神奇之處在哪里?

3.python2是怎樣處理unicode編碼的?

4.python3是怎樣處理unicode編碼的?

 

 

 

1.為什么python用unicode編碼呢?

主要有:

1.處理非英文的內容;

2.可以使用第三方庫;

3.接受任何的輸入內容;

 

在網頁應用和數據庫的交互以及命令行腳本處理都可以用到python。

上面這個報錯的例子就是命令行腳本的例子。

 

 

大家都知道,其實就是一串字節流(1byte:字節),一個字節就是8位二進制數,10進制的8位是千萬,這個二進制的8位就叫做1個字節。1個二進制位只能夠表示0或者1。所以1個字節可以表示2的8次方種可能。扯遠了。。。。。。。

 

我們這個字符串時utf-8編碼方式編碼的。什么叫編碼方式呢?就是說這么一串01010101010101……是按照什么樣的規則轉換成字符的,為什么顯示出來會像我們看到的一樣?

utf-8就是其中一種規則。

 

unicode編碼每一個字符占兩個字節,也就是16個bit位咯!!!如果是其他編碼的話,這16bit位可能表示的別的內容。

如今python標准庫已經支持100多種編碼方式了。

我們不用print,直接a就會看到原始的內容:’sdfs\xe5\xae\xb6\xe9\x87\x8c\xe5\x8f\x91\xe7\x94\x9f\xe7\x9a\x84\xe7\xba\xa0\xe7\xba\xb7'

這個就是在內存中的表示方式,前面的英文可以顯示出來,后面的因為是中文,不能夠直接翻譯出來,人家也不會嘛。。。這些都是16進制,4個2進制只需要1個16進制咯。

 

utf-8是asciil編碼的一種擴展。每個字符是一個字節。所以一個有2的8次方 (2的平房為4,4次方為16,6次方64,8次方就是256),因為是256種可能。但是為什么標准教程上說是128呢?這個等我回去查一下資料再說吧。。可能是ascii庫只有128種字符,還有一半的就浪費了哦。

 

非英文的就不能用ascii來編碼,比如說:d = ‘廖’,然后d.encode(d),這樣就會爆下面的錯:

 

>>> d.encode('ascii')

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in position 0: ordinal not in range(128)

 

 

在python中:類型關系如下:

<type 'basestring'>

  |

  +--<type 'str'>

  |

  +—<type’unicode'>

 

對字符串a使用decode(encoding)就會得到unicode類型,a為unicode類型的時候a.encode(encoding)就會得到str類型了。

 

>>> print a

sdfs家里發生的糾紛

>>> len(a)

25

 

>>> a[-1]

‘\xb7'

 

 

>>> a_uni = a.decode('utf-8')

>>> a_uni

u'sdfs\u5bb6\u91cc\u53d1\u751f\u7684\u7ea0\u7eb7'

>>> type(a_uni)

<type 'unicode'>

 

 

>>> len(a_uni)

11

 

>>> a_uni[-1]

u’\u7eb7'

 

unicode是:

一種不用字節的形式來表示文本;就是說是變長的,len就是個數。

每次中語言的每一個字符都有唯一的數字來表示。

支持所有主流的語言;

可以表示超過100萬的符號;

 

如果ascii, utf-8 和其他的字節串 是文本,那么unicode就是文本性的,unicode時最嚴格的文本格式;unicode是最嚴格的。這是文字的抽象格式。

 

unicode是一種概念:

為unicode保存到硬盤,就必須進行編碼

>>> a = unicode('AB')

>>> type(a)

<type 'unicode'>

>>> a.encode(‘utf-8’)#這就是編碼成了utf-8編碼了。

'AB'

 

utf-8

就是變量的多字節表示。

前128個字符就和ascii一樣。(其他的1字節表示不了,需要更多字節,一個字符可能需要1-4個字節)

 

 

 

>>> a = unicode('AB')

>>> a.encode('utf-16')

‘\xff\xfeA\x00B\x00’

utf-16

多字節表示。

2-4個字節表示一個字符;

是對2個字節范圍內的字符舉行優化;

 

utf-32

固定寬度的字符,最快

4個字節32位表示一個字符;

python不支持

 

 

解碼文字轉換為unicode

 

大多數情況都是自動的。

這種情況主要發生在第三個庫。

python會為你解碼的。

 

 

往一個ascii編碼格式的文件里寫入unicode編碼的文字時會報錯的。

 

如果要寫,可以先將字符a.encode(sys.getdefaultencoding())

 

 

 

python2的默認方式是ascii

 

 

可以用:sys.setdefaultencoding(‘utf-8’)來設置python的編碼方式。這個設置當次有效。

但是設置會有更多的麻煩。

 

 

 

解碼:

 

1.解碼

2.unicode編碼無處不在

3.編碼

 

 

轉換為unicode:

 

def to_unicode_or_bust(obj, encoding = ‘utf-8’):

if isinstance(obj, basestring):

if not isinstance(obj, unicode):

obj = unicode(obj, encoding)

return obj

 

轉換為str類型:

主要用在寫入磁盤活着print出來的時候:

直接encode(encoding)即可。

 

 

open文件指定編碼方式,在第三個參數:

f = open(’1.txt’, ‘r’, encoding = ’utf-8’)

content = f.read()

f.close()

這樣就是utf-8的方式讀了。寫也是一個道理。

 


免責聲明!

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



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