python 2.7編碼問題,着實使人頭疼不已,這兩天抽閒想真正弄明白。須要弄清楚這個問題,首先須要明白ASCII,Unicode 和 UTF-8之間的關係。python
進行對上述幾種概念進行描述以前,先進行簡單的總結:windows
一、第一個階段,計算機出現初期,計算機中用8位表示一個字節,共256種狀態,用來表示英文、標點、以及其餘的一些特殊符號(控制碼)等,已經足夠了,這種方式被你們成爲是ANSI的ASCII編碼網絡
二、隨着計算機慢慢滲透到其餘國家,127種狀態已經不能知足需求,好比中文經常使用的字符上萬種,中國人民基於ASCII編碼對中文進行擴充改造,因而出現了GB2312,但因爲漢字實在太多,因此後面又出現了GBK、GB18030python2.7
三、和咱們國家的狀況相似,都有本身的編碼系統,若是不安裝相應的解碼系統,那就只有亂碼了編碼
四、ISO這個組織終於看不下去了,因而規定了一種字符集,包括目前世界上全部的字符code
五、UNICODE 在網絡傳輸中,出現了兩個標準 UTF-8 和 UTF-16,分別每次傳輸 8個位和 16個位。因而就會有人產生疑問,UTF-8 既然能保存那麼多文字、符號,爲何國內還有這麼多使用 GBK 等編碼的人?由於 UTF-8 等編碼體積比較大,佔電腦空間比較多,若是面向的使用人羣絕大部分都是中國人,用 GBK 等編碼也能夠。blog
1、ASCII編碼utf-8
計算機內部的全部信息都是由二進制表示,每一位均可以用0和1兩種狀態表示,8位共能夠表示256種狀態,8位二進制表示一個字節,則一個字節能夠表明256字符,由於英文用128個字符表示已經足夠了,則ASCII碼只用了128個字符編碼,最高位0位,2的7次方恰好爲128。unicode
咱們能夠知道ASCII碼錶示英文沒有問題,可是世界上還有其它許多種的字符,ASCII碼確定是表示不了這麼多的字符,須要其它的編碼方式。好比中文經常使用的漢字上數萬個,256種的編碼方式確定不適合,漢字通常使用GB2312編碼。開發
2、ANSI編碼
ANSI能夠認爲是ASCII的擴展集,表示對應當前系統的locale的遺留編碼,根據當前的locale選定具體的編碼,好比簡體中文就是GBK,繁體就是BIG5,其它的有其它的編碼方式,因此ASCII的擴展集,不一樣語言地域使用的是不同的,因此各國都有本身的編碼規則,相互不能兼容,因此ISO牽頭着手解決了這個問題,因而推出了下面的Unicode編碼
3、Unicode編碼
由上一節咱們能夠知道,如今存在多種編碼方式,咱們在解碼文件的時候,就必定知道其編碼方式,不然解碼的時候就會出現亂碼。Unicode能夠包括100多萬的字符,每一種字符都存在惟一的編碼,可是須要Unicode是字符集,而並無規定字符的存儲方式。Unicode規定每個字符須要用3個字節或者4個字節表示,可是對於英文字符只須要一個字符表示,這種字節的浪費是不能接受的。
4、UTF-8編碼
UTF-8是一種可變長的編碼,字節爲1~4字節,值得注意的是UTF-8與Unicode的關係是:前者是後者的一種實現方式。
UTF-8編碼有兩種規則:
一、對於單字節,首位BIT爲0,這與ASCII保持一致,編碼也與ASCII同樣,徹底兼容了ASCII編碼
二、對於多字節,好比N個字節,第一個字節前N位爲1,第N+1位爲0,後續字節的前兩位爲10,其它所有爲字符的Unicode編碼。
由上可知,若是是UTF-8編碼,若是首位爲0,表示該字符編碼佔一個字節,若是首位不爲0,有幾個1,就表示一共佔幾個字節
UTF編碼在windows平臺下,默認帶BOM(unicode協議規定的碼點),好比你在記事本上編輯的代碼,都會帶有這個所謂的碼頭;這樣的是不能跨平臺處理的;由於Linux/Unix是不會解析這個BOM。因此建議windows開發的同窗,建議使用Notepad++,並使用無BOM方式保存。
固然還有UTF-1六、UTF-32等編碼方式,你會發如今windows平臺下,用記事本保存爲UNICODE,其碼值對應就是UTF-16,可是不能說在windows上unicode就是utf-16,緣由前面已經說了。
4、舉個例子
打開記事本,輸入「中」,而後以不一樣的編碼方式存儲。
而後能夠用「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。
4、Python編碼問題
終於進入主題,Python2.7中文編碼的時候容易出現亂碼。其緣由是你提供字符的編碼與默認的編碼格式不一致。好比在windows平臺(簡中)上,cmd中斷默認的編碼是gdk,你在cmd中窗口中,以gdk解碼成unicode是沒有問題的,可是要是以utf-8進行解碼,是會報錯的。
若是是在cmd下想採用utf-8的編碼怎麼辦呢?先解碼成unicode而後再採用utf-8進行編碼,其餘的編碼轉換方式相似,先解碼再編碼。
總之,在python2.7版本上,要想不亂碼,就須要使文本的編碼與平臺默認的編碼方式一致,這樣就不會出現亂碼了。 文中部份內容來自網絡,若是涉及侵權,請聯繫我。