最近在學習python的時候遇到了字符集的相關內容,感覺有點迷糊,寫點筆記,查缺補漏一下
字符編碼基本內容
計算機只認識二進制,所以生活中的各種進制的數字都必須轉換爲二進制才能讓機器理解,而文字和數字沒有關係,所以約定一張表,將文字和數字相對應上,這樣就可以根據數字來找到對應的文字。
中國常用編碼介紹一覽表
編碼 | 制定時間 | 作用 | 所佔字節數 |
---|---|---|---|
ASCII | 1967年 | 表示英語及西歐語言 | 8bit/1bytes |
GB2312 | 1980年 | 國家簡體中文字符集,兼容ASCII | 2bytes |
Unicode | 1991年 | 國際標準組織統一標準字符集 | 2[通常]-4bytes |
GBK | 1995年 | GB2312的擴展字符集,支持繁體字,兼容GB2312 | 2bytes |
UTF-8 | 1992年 | 不定長編碼 | 1-3bytes[通常],4-6bytes |
部分字符集
ASCII
ASCII(American Standard Code for Information Interchange,美國信息交換標準代碼),是單字節編碼系統,通常情況下前128個是ASCII編碼,後128個稱爲擴展ASCII碼,主要顯示英語以及某些符號,如下圖所示,是一張ASCII碼錶
圖片引用百度百科
備註:在計算機中,1個字節定義爲8位,用來解決‘斷句’的問題,所以1個bit(比特)是最小的表示單位,一個字節是最小的存儲單位
GB2312和GBK以及其他的地方編碼
對於部分國家和地區來說,256個字符無法對應自己的所有文字,所以就制定了滿足地方文字的編碼集,比如,
中文編碼(GBK,GB2312,GB18030)
韓文編碼(ks_c_5601-1987)
日本編碼(Shift_JIS)
泰文編碼(TIS-620)
Unicode
每個國家都有自己的標準,那麼在國際交流的時候會帶來不便,除非你安裝相應的編碼集,所以,萬國碼-Unicode誕生了,Unicode把所有的文字都統一到一套編碼裏,涵蓋了幾乎全球所有的文字和二進制的對應關係,解決了亂碼的問題。
Unicode一個字符用2-4個字節來表示,通常是兩個字節就可以表述一個字符,並且現代操作系統和大多數編程語言都支持Unicode。但是對於純英文的內容的話,使用Unicode編碼將會比ASCII編碼多出一倍的空間大小,在存儲和傳輸上不太合適。
UTF-8
由於Unicode的瑕疵,所以出現了“可變長編碼”的UTF(Unicode Transformation Format)-8編碼,對Unicode的字符進行轉換,以便在存儲和網絡傳輸時節省空間。
小結
理解了ASCII,Unicode和UTF-8,字符編碼的工作方式:
在計算機內存中,統一使用Unicode編碼,當需要保存到硬盤或者進行傳輸的時候,就轉換爲UTF-8編碼。比如:用記事本編輯的時候,從文件讀取的UTF-8字符被轉換爲Unicode字符到內存裏,編輯完成後保存的時候,再把Unicode轉換爲UTF-8保存在文件中。
Python3和Python2的編碼
Python3的解釋器在將字符加載到內存中的時候會默認將字符集轉成了Unicode,但是Python2卻不會,你的文件編碼聲明是什麼,加載到內存中就是什麼編碼,這意味着如果環境和聲明的編碼方式不一樣,那麼就算使用UTF-8,依然可能會出現亂碼。
Python3的執行過程
- 解釋器找到代碼文件,把代碼字符串按文件頭(在python3中如果沒有文件頭定義編碼方式,默認是UTF-8)定義的編碼加載到內存,轉成Unicode。
- 把代碼字符串按照語法規則進行解釋。
- 所有的變量字符都會以Unicode編碼聲明。
Python2的執行過程
既然Python3能將編碼轉成Unicode,那麼可能是調用了decode(解碼)
和encode(編碼)
。
UTF-8/GBK... --> decode 解碼 -->Unicode
Unicode --> encode 編碼 --> UTF-8/GBK...
常見的編碼錯誤原因
Python如果出現了編碼問題,可以按照以下方面進行排查:
- Python解釋器的默認編碼
- Python源文件文件編碼
- Terminal使用的編碼
- 操作系統的語言設置