前言
字符編碼非常容易出問題,我們要牢記幾句話:
1.用什么編碼保存的,就要用什么編碼打開
2.程序的執行,是先將文件讀入內存中
3.unicode是父編碼,只能encode解碼成其他編碼格式
utf-8,GBK這些是子8編碼,只能decode編碼成Unicode
一、什么是字符編碼
我們知道,計算機只能識別二進制,我們平時寫的代碼都需要轉成二進制才能被計算機識別。所以,我們寫的字符怎么轉換成二進制呢,這個過程實際就是通過一個標準使我們寫的字符與特定數字一一對應,這個標準就稱為字符編碼。
字符------(字符編碼)------->數字
二、字符編碼發展歷程
1.ASCII碼
計算機起源于美國,字符編碼也起源于美國。但是美國人民使用的文字只有26個字母,再加上些特殊符號就搞定了。不像我們中國,小學生就要認識幾千個漢字。所以美國人民就使用了ASCII碼(美國信息交換標準碼)作為字符編碼,一個Bytes代表一個字符,1Bytes=8bit,可以有2的8次方即256中不同的變化,但最初只用了前7位,即127個字符,已經足夠美國人民使用了(當然也出于成本的考慮)。后來將拉丁文編入第8位,至此,ASCII碼就被占滿了,英語國家和拉丁國家可以愉快的玩耍了。
2.GBK
別看咱們中國暫時科技比不上美帝國,但是咱們有一顆積極向上的心啊,于是,在1980年,國家標準總局發布了中文使用的字符編碼-->GBK,使用兩個字節表示一個漢字,這樣就有2的16次方即65536種組合,已經足夠漢字使用了。
同時,其他國家也分別發布了自己國家的字符編碼標準,如日本的shift_JIS,韓國的Euc-kr等等
3.Unicode
據說,字符編碼鼎盛時期有數百種,且彼此間互相不支持,看來各國人民都很有骨氣,但是這太不利于世界的互通了,于是Unicode應運而生。1994年,國際標準化組織發布了號稱萬國碼的Unicode,用兩個字節表示一個字符,有65536種組合,已經能把全世界絕大多數語言包括了。
4.utf-8
Unicode雖然好,但有一個問題,本來用一個字節就能表示的英文,現在要用兩個字節,存儲空間平白多出一倍,這顯然是不完美的,所以又產生了utf-8,對英文字符只用1個字節,對中文字符用3個字節來表示。
5.Unicode所有字符都是兩個字節,簡單粗暴,字符轉換成數字的速度快,但是占用存儲空間大
utf-8對不同的字符采用不用的長度表示,節省空間,但是轉換效率不如Unicode快
內存中使用的字符編碼是Unicode,內存就是為了加快速度的,所以寧肯犧牲一點空間,也要保證速度
硬盤和網絡傳輸是用utf-8的,因為磁盤I/O或者網絡I/O延遲要遠大于utf-8的轉換效率,并且在網絡傳輸中應該盡可能節省帶寬
三、Python解釋器執行
第一階段:python解釋器啟動,此時就相當于啟動了一個文本編輯器
第二階段:python解釋器作為文本編輯器,去打開t.py文件,從硬盤上將t.py的文件內容讀入到內存中
第三階段:python解釋器解釋執行剛剛加載到內存中t.py的代碼
其中第二階段,t.py文件在保存時有一個字符編碼,在Python解釋器打開文件時也要指定一樣的編碼方式(Python2默認的編碼方式是ASCII,Python3默認是utf-8),如果文件保存的編碼格式和Python解釋器默認的編碼方式不一樣,就要在文件的開頭寫上#coding: ,來告訴python解釋器不要用自己默認的編碼方式來讀,而是要用頭文件指定的方式來讀文件,這樣才不會出錯。
第三階段:讀取已經加載到內存中的代碼(默認是Unicode),然后執行,執行過程中如果碰到類似定義變量的操作,就會在內存中開辟一塊新的內存空間。此時注意,新開辟的內存空間不一定也是Unicode,用戶可以在定義變量的時候指定編碼方式,定義時開辟的內存空間,也只是一塊空間而已,可以存放任意編碼格式的代碼。以Python3為例

四、編碼解碼
保存文件是把內存中的文件保存到硬盤上
讀文件是把硬盤中的文件讀到內存

Unicode是父編碼,utf-8,GBK這些是子編碼,如果子碼想轉換成其他編碼,必須要先轉換成父編碼,再由父編碼轉換成其他子編碼
解碼就是decode,是由子碼轉成父碼Unicode的過程
編碼就是encode,是由Unicode轉換成其他編碼的過程
之前說過,文件讀入內存中,就成了Unicode編碼(當然這是默認情況,也可以根據指令更改),從硬盤讀文件的過程就是把硬盤中的utf-8解碼成Unicode
文件保存時,就是由內存保存到硬盤的過程,硬盤中是utf-8的編碼方式,需要由Unicode編碼成utf-8
五、Python2和Python3的區別
1.Python2的默認編碼方式是ASCII,打開utf-8保存的文件時會報錯,應該在頭文件上加#coding : utf-8
Python2中的str被識別為Bytes,所以Python2中的str是被編碼后的結果,其實會默認做一件事,就是在str前面加一個u,先轉換成Unicode,在encode成bytes
Python2中有兩種字符串類型,str和Unicode,str可以通過在前面加個‘u'來轉換成Unicode
2.python 3 的默認編碼方式是utf-8,可以直接打開用utf-8保存的文件
Python3中的str被識別成Unicode
Python3中也有兩種字符串類型(bytes和str),但bytes就是bytes,str是unicode
六、打印到終端
首先要知道,Windows的終端的默認編碼方式是GBK
終端也是應用程序,是運行在內存中的,所以我們用print()打印的過程,是從內存中到內存中。所以對于unicode,怎么打印都不會出錯,但是Python2中除了加‘u'的字符串外,其他的字符串是Bytes,此時終端中是GBK編碼,而Python2中是指定的utf-8或者默認的ascii碼時,在終端中打印就會出錯。
這些是我目前的理解,如果我以后意識到錯誤或者有表述不清的地方,再來修改。唉,字符編碼是個坑啊
以上這篇老生常談Python基礎之字符編碼就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持VEVB武林網。
新聞熱點
疑難解答