8 字符編碼
學習字符編碼的計算機基礎儲備
1、計算機軟件運行基礎圖解
2、文本編輯器存取文件原理。(nodepad++,pycharm,word)
打開編輯器就打開了一個進程,是在內存中的,所以在編輯器編寫的內容也都是存放與內存中的,斷電後數據丟失。因而需要保存到硬盤上,點擊保存按鈕,就從內存中把數據刷到了硬盤上。
在這一點上,我們編寫一個py文件(沒有執行),跟編寫其他文件沒有任何區別,都只是在編寫一堆字符而已。
3. python解釋器執行py文件的原理 ,例如python test.py
第一階段:python解釋器啟動,此時就相當於啟動了一個文本編輯器,進入內存
第二階段:python解釋器相當於文本編輯器,去打開test.py文件,從硬盤上將test.py的文件內容讀入到內存中(小復習:pyhon的解釋性,決定了解釋器只關心文件內容,不關心文件後綴名)
第三階段:python解釋器解釋執行剛剛加載到內存中test.py的代碼( ps:在該階段,即執行時,才會識別python的語法,執行文件內代碼,執行到name="egon",會開辟內存空間存放字符串"egon")
在前兩個階段中python解釋器和文本編輯器是相同的唯一的不同是到了第三個階段文本編輯器將內容讀入內存是為了顯示/編輯,而python解釋器是為了執行。
什麽是字符編碼
計算機只認識又0,1組成的數字。而我們平時在使用計算機時,用的都是人類能讀懂的字符(用高級語言編程的結果也無非是在文件內寫了一堆字符)。想讓計算機看得懂我們所寫的內容必須經過一個過程:
字符---------->翻譯過程---------->數字
這個過程實際就是一個字符如何對應一個特定數字的標準,這個標準稱之為字符編碼
以下兩個場景下涉及到字符編碼的問題:
1. 一個python文件中的內容是由一堆字符組成的(python文件未執行時)
2. python中的數據類型字符串是由一串字符組成的(python文件執行時)
字符編碼的發展
1、ASCII
現代計算機起源於美國,最早誕生也是基於英文考慮的ASCII
ASCII:一個Bytes代表一個字符(英文字符/鍵盤上的所有其他字符),1Bytes=8bit,8bit可以表示0-2**8-1種變化,即可以表示256個字符
ASCII最初只用了後七位,127個數字,已經完全能夠代表鍵盤上所有的字符了(英文字符/鍵盤的所有其他字符)後來為了將拉丁文也編碼進了ASCII表,將最高位也占用了
2、百花齊放
為了滿足中文,中國人定制了GBK
GBK:2Bytes代表一個字符
為了滿足其他國家,各個國家紛紛定制了自己的編碼
日本把日文編到Shift_JIS
裏,韓國把韓文編到Euc-kr
裏 ... ...
3、分久必合終歸一統
各國有各國的標準,就會不可避免地出現沖突,結果就是,在多語言混合的文本中,顯示出來會有亂碼。於是產生了unicode,統一用2Bytes代表一個字符,2**16-1=65535,可代表6萬多個字符,因而兼容萬國語言
但對於通篇都是英文的文本來說,這種編碼方式無疑是多了一倍的存儲空間。於是產生了UTF-8,對英文字符只用1Bytes表示,對中文字符用3Bytes
4、註意:
unicode:簡單粗暴,所有字符都是2Bytes,優點是字符->數字的轉換速度快,缺點是占用空間大
utf-8:精準,對不同的字符用不同的長度表示,優點是節省空間,缺點是:字符->數字的轉換速度慢,因為每次都需要計算出字符需要多長的Bytes才能夠準確表示
1)內存中使用的編碼是unicode,用空間換時間(程序都需要加載到內存才能運行,因而內存應該是盡可能的保證快)
2)硬盤中或者網絡傳輸用utf-8,網絡I/O延遲或磁盤I/O延遲要遠大與utf-8的轉換延遲,而且I/O應該是盡可能地節省帶寬,保證數據傳輸的穩定性。
字符編碼的實際應用
unicode----->encode-------->utf-8
utf-8-------->decode---------->unicode
1、亂碼
文件從內存刷到硬盤的操作簡稱存文件
文件從硬盤讀到內存的操作簡稱讀文件
1)亂碼一:存文件時已亂碼
例如存文件時,由於文件內有各個國家的文字,我們單以日本的編碼shiftjis去存,
本質上其他國家的文字由於在shiftjis中沒有找到對應關系而導致存儲失敗,‘你瞅啥‘在shiftjis中找不到對應關系‘何を見て\n‘可以找到對應關系。但當我們用文件編輯器去存的時候,編輯器會幫我們做轉換,保證中文也能用shiftjis存儲(硬存,必然亂碼),這就導致了,存文件階段就已經發生亂碼此時當我們用shiftjis打開文件時,日文可以正常顯示,而中文則亂碼了。或者:
f=open(‘a.txt‘,‘wb‘) f.write(‘何を見て\n‘.encode(‘shift_jis‘)) f.write(‘你愁啥\n‘.encode(‘gbk‘)) f.write(‘你愁啥\n‘.encode(‘utf-8‘)) f.close()
以任何編碼打開文件a.txt都會出現其余兩個無法正常顯示的問題(open,write是下一個文件處理的知識點不是大家的關註點,只需要看編碼部分即可)
2)亂碼二:存文件是沒亂碼讀文件時亂碼
存文件時用utf-8編碼,保證兼容萬國,不會亂碼,而讀文件時選擇了錯誤的解碼方式,比如gbk,則在讀階段發生亂碼,讀階段發生亂碼是可以解決的,選對正確的解碼方式就ok了,而存文件時亂碼,則是一種數據的損壞。
總結:
無論是何種編輯器,要防止文件出現亂碼核心法則就是,文件以什麽編碼保存的,就以什麽編碼方式打開
2、註意:
文件test.py以gbk格式保存,內容為:x=‘林‘
無論是python2 test.py
還是python3 test.py
都會報錯(因為python2默認ascii,python3默認utf-8)
除非在文件開頭指定#coding:gbk
重點總結
1、以什麽編碼存的就要以什麽編碼取出
ps:內存固定使用unicode編碼,
我們可以控制的編碼是往硬盤存放或者基於網絡傳輸選擇編碼
2、數據是最先產生於內存中,是unicode格式,要想傳輸需要轉成bytes格式
#unicode----->encode(utf-8)------>bytes
拿到bytes,就可以往文件內存放或者基於網絡傳輸
#bytes------>decode(gbk)------->unicode
3、python3中字符串被識別成unicode
python3中的字符串encode得到bytes
4、了解
python2中的字符串就bytes
python2中在字符串前加u,就是unicode
8 字符編碼