天天看點

字元編碼

原文出處:https://www.cnblogs.com/alex3714/articles/7550940.html

編碼種類

  • ASCII占1個位元組,隻支援英文
  • GB2312占2個位元組,支援6700+漢字
  • GBK GB2312的更新版,支援21000+漢字
  • Shift-JIS日本字元
  • TIS-620 泰國編碼

由于每個國家都有自己的字元,是以其對應關系也涵蓋了自己國家的字元,但是以上編碼都存在局限性,即:僅涵蓋本國字元,無其他國家字元的對應關系。應運而生出現了萬國碼,他涵蓋了全球所有的文字和二進制的對應關系

  • unicode 2-4位元組,已經收錄了136690個字元,一直在不斷增長..

Unicode起到了兩個作用:

  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進制。

需要注意的是,以某種編碼存到硬碟,從硬碟讀出來的時候就必須用那種編碼讀,要不然就亂了。

python3的執行過程

  1. 解釋器找到代碼檔案,把代碼字元串按檔案頭定義的編碼加載到記憶體,轉成unicode
  2. 把代碼字元串按照文法規則進行解釋
  3. 所有的變量字元都會以unicode編碼聲明

如果使用python3的話,我們用utf8編碼的檔案可以在windows下的終端(gbk)正常顯示,是因為到了記憶體裡python解釋器會把utf8轉成unicode,在輸出的時候,如果你的終端是gbk編碼的或者是utf8編碼的,python3就會把unicode轉成gbk或utf8。(unicode可以和任意編碼格式靈活轉換)

但僅限于python3,并不是所有的變成語言在記憶體裡預設編碼都是unicode的,比如 python2就不是,它的預設編碼是ASCII,想寫中文,就必須聲明檔案頭的coding為gbk or utf8,聲明之後,python2的解釋器僅以檔案頭聲明的編碼去解釋你的代碼,加載到記憶體後,并不會主動幫你轉成unicode,也就是說,你的檔案編碼是utf-8,加載到記憶體裡,你的變量字元串就也是utf8,意味着,你以utf8編碼的檔案,在windows是亂碼..

既然Python2并不會自動的把檔案編碼轉為unicode存在記憶體裡, 那就隻能使出最後一招了,你自己人肉轉。Py3 自動把檔案編碼轉為unicode必定是調用了什麼方法,這個方法就是,decode(解碼) 和encode(編碼)

UTF-8 --> decode 解碼 --> Unicode
Unicode --> encode 編碼 --> GBK / UTF-8 ..
      

python bytes類型

在python2中,byte==str, unicode是一個單獨類型

由于Python創始人在開發初期認知的局限性,其并未預料到python能發展成一個全球流行的語言,導緻其開發初期并沒有把支援全球各國語言當做重要的事情來做,是以就輕佻的把ASCII當做了預設編碼。 當後來大家對支援漢字、日文、法語等語言的呼聲越來越高時,Python于是準備引入unicode,但若直接把預設編碼改成unicode的話是不現實的, 因為很多軟體就是基于之前的預設編碼ASCII開發的,編碼一換,那些軟體的編碼就都亂了。是以Python 2 就直接 搞了一個新的字元類型,就叫unicode類型,比如你想讓你的中文在全球所有電腦上正常顯示,在記憶體裡就得把字元串存成unicode類型

python3 unicode==str, byte是一個單獨的類型

為什麼在py3裡,把unicode編碼後,字元串就變成了bytes格式? 你直接給我直接列印成gbk的字元展示不好麼?我想其實py3的設計真是煞費苦心,就是想通過這樣的方式明确的告訴你,想在py3裡看字元,必須得是unicode編碼,其它編碼一律按bytes格式展示。

最後再提示一下,Python隻要出現各種編碼問題,無非是哪裡的編碼設定出錯了

常見編碼錯誤的原因有:

  • python解釋器的預設編碼
  • python源檔案檔案編碼
  • Terminal使用的編碼
  • 作業系統的語言設定