Python常見字元編碼間的轉換

來源:互聯網
上載者:User

標籤:自己   odi   .com   mil   進位   div   手動   今天   作用   

  學習Python,字元編碼間的轉換是繞不過去的一隻攔路虎,不把編碼徹底搞明白,總有一天它會猝不及防坑你一把。

  Python2.x和Python3.x在字元編碼的設定上也有很大區別(Python3未來將是主流,所以Python3為主),今天我們就來一起學習下。

  上一篇文章裡我已經簡述了Python的常見編碼了,這裡就不再贅述了,還不清楚的小夥伴可以先去看下:               http://www.cnblogs.com/schut/p/8406897.html

一、Unicode 和 UTF-8的糾葛  

  Unicode 起到了2個作用:

  1. 直接支援全球所有語言,每個國家都可以不用再使用自己之前的舊編碼了,用unicode就可以了。(就跟英語是全球統一語言一樣)
  2. unicode包含了跟全球所有國家編碼的映射關係。

    Unicode解決了字元和二進位的對應關係,但是使用unicode表示一個字元,太浪費空間。例如:利用unicode表   示“Python”需要12個位元組才能表示,比原來ASCII表示增加了1倍。由於電腦的記憶體比較大,並且字串在內容中表示時也不會特別大,所以內容可以使用unicode來處理,但是儲存和網路傳輸時一般資料都會非常多,那麼增加1倍將是無法容忍的!!!

  為瞭解決儲存和網路傳輸的問題,出現了Unicode Transformation Format,學術名UTF,即:對unicode中的進行轉換,以便於在儲存和網路傳輸時可以節省空間的!

  UTF-8: 使用1、2、3、4個位元組表示所有字元;優先使用1個字元、無法滿足則使增加一個位元組,最多4個位元組。英文佔1個位元組、歐洲語系佔2個、東亞佔3個,其它及特殊字元佔4個。

  UTF-16: 使用2、4個位元組表示所有字元;優先使用2個位元組,否則使用4個位元組表示。

  UTF-32: 使用4個位元組表示所有字元。

  總結:UTF 是為unicode編碼 設計 的一種 在儲存 和傳輸時節省空間的編碼方案。

二、字元在硬碟上的儲存

  首先要明確的一點就是,無論以什麼編碼在記憶體裡顯示字元,存到硬碟上都是2進位。理解這一點很重要。

  比如:    

    ascii編碼(美國):        l   0b1101100        o   0b1101111        v   0b1110110        e   0b1100101    GBK編碼(中國):        老   0b11000000 0b11001111        男   0b11000100 0b11010000        孩   0b10111010 0b10100010

  還要注意的一點是,
要注意的是,存到硬碟上時是以何種編碼存的,再從硬碟上讀出來時,
就必須以何種編碼讀(開頭聲明或轉換),要不然就亂了。

三、編碼的轉換
  
雖然有了unicode and utf-8 ,但是由於曆史問題,各個國家依然在大量使用自己的編碼,
比如中國的windows,預設編碼依然是gbk,而不是utf-8。
  基於此,如果中國的軟體出口到美國,在美國人的電腦上就會顯示亂碼,因為他們沒有gbk編碼。
  所以該怎麼辦呢?
  還記得我們講unicode其中一個功能是其包含了跟全球所有國家編碼的映射關係,這時就派上用場了。
無論你以什麼編碼儲存的資料,只要你的軟體在把資料從硬碟讀到記憶體裡,轉成unicode來顯示,就可以了。
由於所有的系統、程式設計語言都預設支援unicode,那你的gbk軟體放到美國電腦上,載入到記憶體裡,變成了unicode,
中文就可以正常展示啦。
 
 Python3執行過程
  1. 解譯器找到代碼檔案,把代碼字串按檔案頭定義的編碼載入到記憶體,轉成unicode
  2. 把代碼字串按照文法規則進行解釋
  3. 所有的變數字元都會以unicode編碼聲明
  在py3上 把你的代碼以utf-8編寫, 儲存,然後在windows上執行。
  發現可以正常執行!
  其實utf-8編碼之所以能在windows gbk的終端下顯示正常,是因為到了記憶體裡python解譯器把utf-8轉成了unicode ,
但是這隻是python3, 並不是所有的程式設計語言在記憶體裡預設編碼都是unicode,比如 萬惡的python2 就不是,
是ASCII,想寫中文,就必須聲明檔案頭的coding為gbk or utf-8, 聲明之後,python2解譯器
僅以檔案頭聲明的編碼去解釋你的代碼,載入到記憶體後,並不會主動幫你轉為unicode,也就是說,你的檔案編碼是utf-8,
載入到記憶體裡,你的變數字串就也是utf-8, 這意味著什嗎?意味著,你以utf-8編碼的檔案,
在windows是亂碼。

其實亂是正常的,不亂才不正常,因為只有2種情況 ,你的windows上顯示才不會亂。Python2並不會自動的把檔案編碼轉為unicode存在記憶體裡,
  1. 字串以GBK格式顯示
  2. 字串是unicode編碼
所以我們只有手動轉,Python3 自動把檔案編碼轉為unicode必定是調用了什麼方法,這個方法就是,decode(解碼) 和encode(編碼)。
方法如下:
  
UTF-8 --> decode 解碼 --> Unicode

  Unicode --> encode 編碼 --> GBK / UTF-8
  例如:
  
#!/usr/bin/env python3#-*- coding:utf-8 -*-# write by congcongs = ‘匆匆‘print(s)s1 = s.decode("utf-8") # utf-8 轉成 Unicode,decode(解碼)需要註明當前編碼格式print(s1,type(s1))s2 = s1.encode("gbk") # unicode 轉成 gbk,encode(編碼)需要註明產生的編碼格式print(s2,type(s2))s3 = s1.encode("utf-8") # unicode 轉成 utf-8,encode(編碼)註明產生的編碼格式print(s3,type(s3))

規則如下:

 
四、如何驗證編碼轉對了呢?

  1、查看資料類型,python 2 裡有專門的unicode 類型

   2、查看unicode編碼映射表

  unicode字元是有專門的unicode類型來判斷的,但是utf-8,gbk編碼的字元都是str,
你如果分辨出來的當前的字串資料是何種編碼的呢? 有人說可以通過位元組長度判斷,
因為utf-8一個中文佔3位元組,gbk一個佔2位元組。
  看輸出的位元組個數,也能大體判斷是什麼類型。精確的驗證一個字元的編碼呢,就是拿這些16進位的數跟編碼錶裡去匹配。
詳細過程可以看這裡:https://www.luffycity.com/python-book/di-3-zhang-python-ji-chu-2014-wen-jian-cao-4f5c26-han-shu/33-zi-fu-bian-ma-zhuan-huan.html

五、Python bytes類型
  把8個二進位一組稱為一個byte,用16進位來表示。為的就是讓人們看起來更可讀。我們稱之為bytes類型,即位元組類型。
  python2的字串其實更應該稱為位元組串。 通過儲存方式就能看出來, 但python2裡還有一個類型是bytes呀,難道又叫bytes又叫字串?
嗯 ,是的,在python2裡,bytes == str , 其實就是一回事。
  除此之外呢, python2裡還有個單獨的類型是unicode , 把字串解碼後,就會變成unicode。
>>> s‘\xe8\xb7\xaf\xe9\xa3\x9e‘ #utf-8>>> s.decode(‘utf-8‘)u‘\u8def\u98de‘ #unicode 在unicode編碼錶裡對應的位置>>> print(s.decode(‘utf-8‘))路飛 #unicode 格式的字元
  Python2的預設編碼是ASCII碼,當後來大家對支援漢字、日文、法語等語言的呼聲越來越高時,Python於是準備引入unicode,但若直接把
預設編碼改成unicode的話是不現實的, 因為很多軟體就是基於之前的預設編碼ASCII開發的,編碼一換,那些軟體的編碼就都亂了。所以Python 2
就直接 搞了一個新的字元類型,就叫unicode類型,比如你想讓你的中文在全球所有電腦上正常顯示,在記憶體裡就得把字串存成unicode類型。
>>> s = "路飛">>> s‘\xe8\xb7\xaf\xe9\xa3\x9e‘>>> s2 = s.decode("utf-8")>>> s2u‘\u8def\u98de‘>>> type(s2)<type ‘unicode‘>

  Python3 除了把字串的編碼改成了unicode, 還把str 和bytes 做了明確區分, str 就是unicode格式的字元, bytes就是單純二進位啦。

  在py3裡看字元,必須得是unicode編碼,其它編碼一律按bytes格式展示。

  Python只要出現各種編碼問題,無非是哪裡的編碼設定出錯了
常見編碼錯誤的原因有以下這些: 

  • Python解譯器的預設編碼
  • Python源檔案檔案編碼
  • Terminal使用的編碼
  • 作業系統的語言設定
最後總結一下:
  python3  檔案預設編碼是utf-8 , 字串編碼是 unicode
        以utf-8 或者 gbk等編碼的代碼,載入到記憶體,會自動轉為unicode正常顯示。

  python2  檔案預設編碼是ascii , 字串編碼也是 ascii , 如果檔案頭聲明了是gbk,那字串編碼就是gbk。
      
 以utf-8 或者 gbk等編碼的代碼,載入到記憶體,並不會轉為unicode,編碼仍然是utf-8或者gbk等編碼。


以上內容搬運和修改自:https://www.luffycity.com/python-book/di-3-zhang-python-ji-chu-2014-wen-jian-cao-4f5c26-han-shu/33-zi-fu-bian-ma-zhuan-huan.html

  

Python常見字元編碼間的轉換

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.