python之字符編碼、存取文件亂碼問題

一、文本編輯器存取文件的原理(nodepad++,pycharm,word)

#1、打開編輯器就打開了啓動了一個進程,是在內存中的,所以,用編輯器編寫的內容也都是存放與內存中的,斷電後數據丟失

#2、要想永久保存,需要點擊保存按鈕:編輯器把內存的數據刷到了硬盤上。

#3、在我們編寫一個py文件(沒有執行),跟編寫其他文件沒有任何區別,都只是在編寫一堆字符而已。

三、python解釋器執行py文件的原理 ,例如python test.py

#第一階段:python解釋器啓動,此時就相當於啓動了一個文本編輯器

#第二階段:python解釋器相當於文本編輯器,去打開test.py文件,從硬盤上將test.py的文件內容讀入到內存中(小複習:pyhon的解釋性,決定了解釋器只關心文件內容,不關心文件後綴名)

#第三階段:python解釋器解釋執行剛剛加載到內存中test.py的代碼( ps:在該階段,即真正執行代碼時,纔會識別python的語法,執行文件內代碼,當執行到name="egon"時,會開闢內存空間存放字符串"egon")

四、python解釋器與文件本編輯的異同

#1、相同點:python解釋器是解釋執行文件內容的,因而python解釋器具備讀py文件的功能,這一點與文本編輯器一樣

#2、不同點:文本編輯器將文件內容讀入內存後,是爲了顯示或者編輯,根本不去理會python的語法,而python解釋器將文件內容讀入內存後,可不是爲了給你瞅一眼python代碼寫的啥,而是爲了執行python代碼、會識別python語法。

五、什麼是字符編碼?

很明顯,我們平時在使用計算機時,用的都是人類能讀懂的字符(用高級語言編程的結果也無非是在文件內寫了一堆字符),如何能讓計算機讀懂人類的字符?

 必須經過一個過程:
  #字符--------(翻譯過程)------->數字 

  #這個過程實際就是一個字符如何對應一個特定數字的標準,這個標準稱之爲字符編碼

六、 以下兩個場景下涉及到字符編碼的問題

#1、一個python文件中的內容是由一堆字符組成的,存取均涉及到字符編碼問題(python文件並未執行,前兩個階段均屬於該範疇)

#2、python中的數據類型字符串是由一串字符組成的(python文件執行時,即第三個階段)

七、字符編碼的發展史與分類

1、歷史演變


階段一:現代計算機起源於美國,最早誕生也是基於英文字符考慮的ASCII


ASCII碼採用8位(1byte)進行編碼

ASCII:一個Bytes代表一個字符(英文字符/鍵盤上的所有其他字符),1Bytes=8bit,8bit可以表示0-2**8-1種變化,即可以表示256個字符

ASCII最初只用了後七位,127個數字,已經完全能夠代表鍵盤上所有的字符了(英文字符/鍵盤的所有其他字符),後來爲了將拉丁文也編碼進了ASCII表,將最高位也佔用了

階段二:爲了滿足中文和英文,中國人定製了GBK


GBK中文采用16位進行編碼,英文還是採用8位編碼

GBK:2Bytes代表一箇中文字符,1Bytes表示一個英文字符
爲了滿足其他國家,各個國家紛紛定製了自己的編碼
日本把日文編到Shift_JIS裏,韓國把韓文編到Euc-kr裏

階段三:各國有各國的標準,就會不可避免地出現衝突,結果就是,在多語言混合的文本中,顯示出來會有亂碼。如何解決這個問題呢???


unicode全部都採用16位編碼,utf-8對英文字符只用1Bytes表示,對中文字符用3Bytes,對其他生僻字用更多的Bytes去存

#!!!!!!!!!!!!非常重要!!!!!!!!!!!!
說白了亂碼問題的本質就是不統一,如果我們能統一全世界,規定全世界只能使用一種文字符號,然後統一使用一種編碼,那麼亂碼問題將不復存在,
ps:就像當年秦始皇統一中國一樣,書同文車同軌,所有的麻煩事全部解決
很明顯,上述的假設是不可能成立的。很多地方或老的系統、應用軟件仍會採用各種各樣的編碼,這是歷史遺留問題。於是我們必須找出一種解決方案或者說編碼方案,需要同時滿足:
#1、能夠兼容萬國字符
#2、與全世界所有的字符編碼都有映射關係,這樣就可以轉換成任意國家的字符編碼

這就是unicode(定長), 統一用2Bytes代表一個字符, 雖然2**16-1=65535,但unicode卻可以存放100w+個字符,因爲unicode存放了與其他編碼的映射關係,準確地說unicode並不是一種嚴格意義上的字符編碼表,下載pdf來查看unicode的詳情:
鏈接:https://pan.baidu.com/s/1dEV3RYp

很明顯對於通篇都是英文的文本來說,unicode編碼採用16位編碼完全就是增大了磁盤IO開銷、延時(二進制最終都是以電或者磁的方式存儲到存儲介質中的)

於是產生了UTF-8(可變長,全稱Unicode Transformation Format),對英文字符只用1Bytes表示,對中文字符用3Bytes,對其他生僻字用更多的Bytes去存

#總結:內存中統一採用unicode,浪費空間來換取可以轉換成任意編碼(不亂碼),硬盤可以採用各種編碼,如utf-8,保證存放於硬盤或者基於網絡傳輸的數據量很小,提高傳輸效率與穩定性。

2、當前字符編碼的形勢

基於目前的現狀,內存中的編碼固定就是unicode,我們唯一可變的就是硬盤的上對應的字符編碼。
此時你可能會覺得,那如果我們以後開發軟時統一都用unicode編碼,那麼不就都統一了嗎,關於統一這一點你的思路是沒錯的,但我們不可會使用unicode編碼來編寫程序的文件,因爲在通篇都是英文的情況下,耗費的空間幾乎會多出一倍,這樣在軟件讀入內存或寫入磁盤時,都會徒增IO次數,從而降低程序的執行效率。因而我們以後在編寫程序的文件時應該統一使用一個更爲精準的字符編碼utf-8(用1Bytes存英文,3Bytes存中文),再次強調,內存中的編碼固定使用unicode。

1、在存入磁盤時,需要將unicode轉成一種更爲精準的格式,utf-8:全稱Unicode Transformation Format,將數據量控制到最精簡

2、在讀入內存時,需要將utf-8轉成unicode
所以我們需要明確:內存中用unicode是爲了兼容萬國軟件,即便是硬盤中有各國編碼編寫的軟件,unicode也有相對應的映射關係,但在現在的開發中,程序員普遍使用utf-8編碼了,估計在將來的某一天等所有老的軟件都淘汰掉了情況下,就可以變成:內存utf-8<->硬盤utf-8的形式了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章