原文出處: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起到了兩個作用:
- 直接支援全球所有語言,每個國家都可以不再使用自己之前的舊編碼了,用unicode就可以了。(就跟英語是全球統一語言一樣)
- 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的執行過程
- 解釋器找到代碼檔案,把代碼字元串按檔案頭定義的編碼加載到記憶體,轉成unicode
- 把代碼字元串按照文法規則進行解釋
- 所有的變量字元都會以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使用的編碼
- 作業系統的語言設定