Python字元編碼

來源:互聯網
上載者:User

      在用python編程中,字串有兩種表示方法"string"和 u"string"。為什麼字串要是用這兩種表達方式,不是只用前一種呢?

      使用type()函數查看,它們分別是str對象和unicode對象。這兩個對象有什麼區別嗎?還有經常用到的encode()和decode()又是幹什麼的呢?都說python指令碼使用的是兩位元組編碼,這又是指什麼呢?

     要回答上面幾個問題,首先得弄清楚關於編碼的幾個概念:
Character Set:字元集,是我們人可以識別的字元。如ASCII規定了127個用一個位元組可以表示的字元集,包括英文字母、數字、符號和一些控制字元。當然ASCII定義的字元集比較小。python中的Character Set基本包括目前世界上所有是用的字元,如中文、英文、日文字元等等。所以基本上所有的字元都可在Python 中進行處理。Code Point :電腦是不能直接識別字元的(因為它只能直接識別二進位碼),所以為了能讓電腦處理和儲存字元,需要將字元對應表成一個數值(因為數值可以用二進位表達,電腦從而就可以識別了),這個數值叫作字元的code point。字元與其code point是一對一映射,Unicode很好的規定了這種映射關係。Encode:unicode雖然規定了每個字元的Code Point,但並沒有規定電腦如何儲存這些Code Point。所有就有了UTF-8、GBK、UTF-16等編碼格式,它們規定電腦如何來儲存這個Code Point,每個編碼格式它們儲存方式都是不相同的。例如,“中”字的Code Point為U+2D2E(U表示Unicode,2D2E表示該Code Point值),使用GBK、Big5、UTF-8、UTF-16四種編碼協議對該Code Point進行編碼,獲得的實際二進位表示如下:
       GBK      Big5        UTF-8     UTF-16 ~~\xD6\xD0  \xA4\xA4  \xE4\xB8\xAD  \x2D\x4E
Decode:對實際的二進位進行解碼,擷取它所代表字元的Code Point。如“\xD6\xD0”使用GBK解碼,將獲得2D2E(“中”的Code Point ),如果使用UTF-8對其進行解碼,就會出錯,因為它不是用UTF-8編碼的。

      上面簡單介紹下字元及編碼解碼的概念,可參考博文《字元的編碼與解碼》。       Python中使用兩種字串表達方式,是為了區分字元與實際表示字元的二進位資訊。unicode對象用來表示字元,它不涉及字元的底層的二進位編碼資訊。str對象是用來表示字元的二進位資訊。一個unicode對象可以使用多種編碼格式(如UTF8、GBK)編碼(encode)成多個str對象,每個str對象表示該字串的一種二進位表達。多個不同的str對象可以解碼成相等的unicode對象(表示字串相同,但記憶體位置不同)。     unicode的存在也是為瞭解決因採用不同編碼格式導致的一些問題,建議大家使用unicode對象來存放字串,統一格式。unicode雖然不規定具體的二進位資訊,但為了存放每個字元的Code Point值,需要兩個位元組,所以說Python採用的是二進位編碼(不知道這麼理解可對?)。     由於str對象沒有屬性指定它的編碼格式,所以對它進行處理時,只能將它看成一個位元組串。當對str對象進行列印或解碼時,且不知道它的編碼格式,那麼python只能用預設編碼格式對其進行操作。如果編碼不匹配,就會出現亂碼或者報錯。str對象:
稱字串,它是字串使用特定編碼格式進行編碼後的二進位表達,實際代表用於儲存二進位資訊的位元組串。所以稱它為“位元組串”更合適。如
>>> str = '你好'   #採用系統設定的編碼格式對“你好”進行編碼,可通過locale命令查看。>>> str'\xe4\xbd\xa0\xe5\xa5\xbd'    #當locale設定為utf8時,'你好'的編碼後的二進位表達,一個六位元組的位元組串

Unicode對象:

用於表達“字元”,因為電腦不用直接識別字元,所以使用Code Point來代替字元。如下:

>>> u"你好"u'\u4f60\u597d'

Code Point 4F60表示“你”,597d表示“好”。它只是一個數值與字元對應表,不用於具體編碼。
       對一個str對象進行解碼,可以獲得它表達字串的Code Point,即unicode對象。對unicode對象進行編碼,可獲得它的實際二進位表達,即str對象。當想把str對象從一中編碼格式轉換成另一種編碼格式時,首先得把str轉換成unicode對象,再從unicode對象轉換成另外一種編碼格式的str對象。下面執行一個str對象從utf8格式到gbk格式的轉換:
>>> str="你好">>> str'\xe4\xbd\xa0\xe5\xa5\xbd'         # 採用OS的utf8編碼格式>>> unicode=str.decode("utf8")     # 解碼成Code Point值 >>> unicodeu'\u4f60\u597d'>>> str_gbk=unicode.encode("gbk")  # 將Code Point編碼成GBK格式>>> str_gbk'\xc4\xe3\xba\xc3'>>> unicode.encode()               # 如果編碼不指定格式,將採用系統預設的編碼格式進行編碼。對於decode也一樣。這裡由於ASCII不能對中文字元編碼,所以出錯了。Traceback (most recent call last):  File "<stdin>", line 1, in <module>UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)>>> u = u"你好"     #首碼u自動把字串從utf8轉換成unicode格式了u'\u4f60\u597d'

寫檔案:
>>> file=open("test.txt", "a")>>> file.write(str)>>> file.write(str_gbk)>>> file.write(unicode)Traceback (most recent call last):  File "<stdin>", line 1, in <module>UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
       從上面看,UTF8格式的str對象和GBK格式的str對象成功的寫入test.txt檔案,然而在將unicode對象寫入檔案時,出現錯誤了。這是為什麼呢?       str對象表示字串經編碼後的二進位資訊,可以直接寫入檔案。然後unicode對象表示的是字串的Code Point值,是抽象的值,用來表示字元,是不能直接寫入檔案的。所以Python試圖使用預設的編碼格式ASCII,對unicode對象進行編碼,然後將結果存入檔案。但是由於ASCII不能對”你好”進行編碼,所以報錯了。
修改系統預設編碼格式:
>>> import sys>>> reload(sys)<module 'sys' (built-in)>>>> sys.setdefaultencoding("gbk")  #不建議這麼用[2]>>> str(unicode)      #使用預設GBK,對unicode("你好")進行編碼,轉成str對象'\xc4\xe3\xba\xc3'>>> unicode.encode()   #使用預設GBK,對unicode("你好")進行編碼,轉成str對象'\xc4\xe3\xba\xc3'>>> "你好".decode()    #因為系統使用UTF8,所以“你好”是UTF8格式的位元組串,使用預設GBK對該位元組串進行解碼,雖然成功運行了,但其結果是不正確的。所以我們需要保證位元組串用什麼格式編碼的,就要用什麼格式解碼。u'\u6d63\u72b2\u30bd'





參考文獻:[1] http://www.newsmth.net/bbscon.php?bid=284&id=84741[2] http://stackoverflow.com/questions/3828723/why-we-need-sys-setdefaultencodingutf-8-in-a-py-script[3] http://www.joelonsoftware.com/articles/Unicode.html[4] http://www.unicode.org/

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.