python2.7 編碼問題


 

  python 2.7編碼問題,着實令人頭疼不已,這兩天抽閑想真正弄明白。需要弄清楚這個問題,首先需要明白ASCII,Unicode 和 UTF-8之間的關系。

  進行對上述幾種概念進行描述之前,先進行簡單的總結:

  1、第一個階段,計算機出現初期,計算機中用8位表示一個字節,共256種狀態,用來表示英文、標點、以及其他的一些特殊符號(控制碼)等,已經足夠了,這種方式被大家成為是ANSI的ASCII編碼

  2、隨着計算機慢慢滲透到其他國家,127種狀態已經不能滿足需求,比如中文常用的字符上萬種,中國人民基於ASCII編碼對中文進行擴充改造,於是出現了GB2312,但由於漢字實在太多,所以后面又出現了GBK、GB18030

  3、和我們國家的情況類似,都有自己的編碼系統,如果不安裝相應的解碼系統,那就只有亂碼了

  4、ISO這個組織終於看不下去了,於是規定了一種字符集,包括目前世界上所有的字符

  5、UNICODE 在網絡傳輸中,出現了兩個標准 UTF-8 和 UTF-16,分別每次傳輸 8個位和 16個位。於是就會有人產生疑問,UTF-8 既然能保存那么多文字、符號,為什么國內還有這么多使用 GBK 等編碼的人?因為 UTF-8 等編碼體積比較大,占電腦空間比較多,如果面向的使用人群絕大部分都是中國人,用 GBK 等編碼也可以。

 

 一、ASCII編碼

  計算機內部的所有信息都是由二進制表示,每一位都可以用0和1兩種狀態表示,8位共可以表示256種狀態,8位二進制表示一個字節,則一個字節可以代表256字符,因為英文用128個字符表示已經足夠了,則ASCII碼只用了128個字符編碼,最高位0位,2的7次方剛好為128。

  我們可以知道ASCII碼表示英文沒有問題,但是世界上還有其它許多種的字符,ASCII碼肯定是表示不了這么多的字符,需要其它的編碼方式。比如中文常用的漢字上數萬個,256種的編碼方式肯定不適合,漢字一般使用GB2312編碼。

二、ANSI編碼

  ANSI可以認為是ASCII的擴展集,表示對應當前系統的locale的遺留編碼,根據當前的locale選定具體的編碼,比如簡體中文就是GBK,繁體就是BIG5,其它的有其它的編碼方式,所以ASCII的擴展集,不同語言地域使用的是不一樣的,所以各國都有自己的編碼規則,相互不能兼容,所以ISO牽頭着手解決了這個問題,於是推出了下面的Unicode編碼

三、Unicode編碼

  由上一節我們可以知道,現在存在多種編碼方式,我們在解碼文件的時候,就一定知道其編碼方式,否則解碼的時候就會出現亂碼。Unicode可以包括100多萬的字符,每一種字符都存在唯一的編碼,但是需要Unicode是字符集,而並沒有規定字符的存儲方式。Unicode規定每一個字符需要用3個字節或者4個字節表示,但是對於英文字符只需要一個字符表示,這種字節的浪費是不能接受的。

四、UTF-8編碼

   UTF-8是一種可變長的編碼,字節為1~4字節,值得注意的是UTF-8與Unicode的關系是:前者是后者的一種實現方式。

  UTF-8編碼有兩種規則:

  1、對於單字節,首位BIT為0,這與ASCII保持一致,編碼也與ASCII一樣,完全兼容了ASCII編碼

  2、對於多字節,比如N個字節,第一個字節前N位為1,第N+1位為0,后續字節的前兩位為10,其它全部為字符的Unicode編碼。

  由上可知,如果是UTF-8編碼,如果首位為0,表示該字符編碼占一個字節,如果首位不為0,有幾個1,就表示一共占幾個字節

  UTF編碼在windows平台下,默認帶BOM(unicode協議規定的碼點),比如你在記事本上編輯的代碼,都會帶有這個所謂的碼頭;這樣的是不能跨平台處理的;因為Linux/Unix是不會解析這個BOM。所以建議windows開發的同學,建議使用Notepad++,並使用無BOM方式保存。

  當然還有UTF-16、UTF-32等編碼方式,你會發現在windows平台下,用記事本保存為UNICODE,其碼值對應就是UTF-16,但是不能說在windows上unicode就是utf-16,原因前面已經說了。

四、舉個例子

       打開記事本,輸入“中”,然后以不同的編碼方式存儲。

  

  然后可以用“UE”查看各種編碼下的十六進制。

  UTF-8對應的十六進制:EF BB BF E4 B8 AD,前面三個字節為BOM,后面三個字節才是“中”對應的編碼,轉換為二進制位:111001001011100010101101

  UNICODE對應的十六進制:FF FE 2D 4E,前面兩個字節表示大/小端,FF FE表示是小端的存儲方式,所以其碼值為4E2D,轉換為二進制位:100111000101101

  由上面的二進制可知,UTF-8與UNICODE之間的轉換,能夠滿足上述的規則的。

  那么問題來了,GBK或者其他地區的編碼如何與UNICODE進行轉換呢?---codepage,所謂codepage就是各國的文字編碼與UNICODE對應關系的映射表。GBK與UNICODE的codepage為936。

  

四、Python編碼問題

  終於進入主題,Python2.7中文編碼的時候容易出現亂碼。其原因是你提供字符的編碼與默認的編碼格式不一致。比如在windows平台(簡中)上,cmd中斷默認的編碼是gdk,你在cmd中窗口中,以gdk解碼成unicode是沒有問題的,但是要是以utf-8進行解碼,是會報錯的。

 

如果是在cmd下想采用utf-8的編碼怎么辦呢?先解碼成unicode然后再采用utf-8進行編碼,其他的編碼轉換方式類似,先解碼再編碼。

 總之,在python2.7版本上,要想不亂碼,就需要使文本的編碼與平台默認的編碼方式一致,這樣就不會出現亂碼了。 文中部分內容來自網絡,如果涉及侵權,請聯系我。

 

 

 


免責聲明!

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



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