前言字元編碼非常容易出問題,我們要牢記幾句話:
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
別看咱們中國暫時科技比不上美帝國,但是咱們有一顆積極向上的心啊,於是,在2023年,國家標準總局發布了中文使用的字元編碼-->gbk,使用兩個位元組表示乙個漢字,這樣就有2的16次方即65536種組合,已經足夠漢字使用了。
同時,其他國家也分別發布了自己國家的字元編碼標準,如日本的shift_jis,南韓的euc-kr等等
3.unicode
據說,字元編碼鼎盛時期有數百種,且彼此間互相不支援,看來各國人民都很有骨氣,但是這太不利於世界的互通了,於是unicode應運而生。2023年,國際標準化組織發布了號稱萬國碼的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直譯器解釋執行剛剛載入到記憶體中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字元編碼
ascii 碼是乙個位元組,通常只能顯示英文本母和數字。unicode碼為了顯示多種語言產生,但是要占用兩個位元組,顯示文字要占用大量空間 utf 8 為了節約空間而生,英文本元只用乙個位元組儲存,中文字元需要三個位元組 character ascii unicode utf 8 a01000000...
python字元編碼
列印python檔案編碼 import sys print sys.getdefaultencoding 中文的乙個字元unicode占用2個位元組。對在於ascii字元占用1個位元組 utf 8中 中文字元佔3個位元組,英文本元占用1個位元組 編碼和轉碼 unicode不能再解碼了 它是基層的 u...
Python字元編碼
在用python程式設計中,字串有兩種表示方法 string 和 u string 為什麼字串要是用這兩種表達方式。不是僅僅用前一種呢?使用type 函式檢視,它們各自是str物件和unicode物件。這兩個物件有什麼差別嗎?還有經經常使用到的encode 和decode 又是幹什麼的呢?都說pyt...