1. 程式人生 > 實用技巧 >(三)python之字元編碼

(三)python之字元編碼

一、引言


1,計算機基礎知識

2,文字編輯器存取檔案的原理(nodepad++,pycharm,word)

# 1、開啟編輯器就打開了啟動了一個程序,是在記憶體中的,所以,用編輯器編寫的內容也都是存放與記憶體中的,斷電後資料丟失

# 2、要想永久儲存,需要點選儲存按鈕:編輯器把記憶體的資料刷到了硬碟上。

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

3,python 的直譯器執行.py檔案的原理,例如 python test.py

"""
第一階段:python直譯器啟動,此時就相當於啟動了一個文字編輯器

第二階段:python直譯器相當於文字編輯器,去開啟test.py檔案,從硬碟上將test.py的檔案內容讀入到記憶體中
        (小複習:pyhon的解釋性,決定了直譯器只關心檔案內容,不關心檔案字尾名)
        
第三階段:python直譯器解釋執行剛剛載入到記憶體中test.py的程式碼
        ( ps:在該階段,即真正執行程式碼時,才會識別python的語法,執行檔案內程式碼,當執行到name="zixi"時,會開闢記憶體空間存放字串"zixi")
"""

4,總結 python 直譯器與文字編輯器的區別:

"""
相同點:python直譯器是解釋執行檔案內容的,因而python直譯器具備讀.py檔案的功能,這一點與文字編輯器一樣

不同點:文字編輯器將檔案內容讀入記憶體後,是為了顯示或者編輯,根本不去理會python的語法,而python直譯器將檔案內容讀入記憶體後,
       可不是為了給你瞅一眼python程式碼寫的啥,而是為了執行python程式碼、會識別python語法
"""

二、字元編碼介紹


1,什麼是字元編碼?

計算機要想工作必須通電,即用‘電’驅使計算機幹活,也就是說‘電’的特性決定了計算機的特性。
電的特性即高低電平(人類從邏輯上將二進位制數1對應高電平,二進位制數0對應低電平),關於磁碟的
磁特性也是同樣的道理。結論:計算機只認識數字

很明顯,我們平時在使用計算機時,用的都是人類能讀懂的字元(用高階語言程式設計的結果也
無非是在檔案內寫了一堆字元),如何能讓計算機讀懂人類的字元?

必須經過一個過程:
# 字元--------(翻譯過程)------->數字 # 這個過程實際就是一個字元如何對應一個特定數字的標準,這個標準稱之為字元編碼

2,以下兩個場景下涉及到字元編碼的問題:

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

# 2,python中的資料型別字串是由一串字元組成的(python檔案執行時,即第三個階段)

3,總結字元編碼的發展可分為三個階段(重要)

# 階段一:現代計算機起源於美國,最早誕生也是基於英文考慮的ASCII
ASCII:一個Bytes代表一個字元(英文字元/鍵盤上的所有其他字元),1Bytes=8bit,8bit可以表示0-2**8-1種變化,即可以表示256個字元

ASCII最初只用了後七位,127個數字,已經完全能夠代表鍵盤上所有的字元了(英文字元
/鍵盤的所有其他字元),後來為了將拉丁文也編碼進了ASCII表,將最高位也佔用了 # 階段二:為了滿足中文和英文,中國人定製了GBK GBK:2Bytes代表一箇中文字元,1Bytes表示一個英文字元 為了滿足其他國家,各個國家紛紛定製了自己的編碼 日本把日文編到Shift_JIS裡,韓國把韓文編到Euc-kr裡 # 階段三:各國有各國的標準,就會不可避免地出現衝突,結果就是,在多語言混合的文字中,顯示出來會有亂碼。如何解決這個問題呢??? # !!!!!!!!!!!!非常重要!!!!!!!!!!!! 說白了亂碼問題的本質就是不統一,如果我們能統一全世界,規定全世界只能使用一種文字元號,然後統一使用一種編碼,那麼亂碼問題將不復存在, ps:就像當年秦始皇統一中國一樣,書同文車同軌,所有的麻煩事全部解決 很明顯,上述的假設是不可能成立的。很多地方或老的系統、應用軟體仍會採用各種各樣的編碼,這是歷史遺留問題。於是我們必須找出一種解決方案或者說編碼方案,需要同時滿足: # 1、能夠相容萬國字元 # 2、與全世界所有的字元編碼都有對映關係,這樣就可以轉換成任意國家的字元編碼 這就是unicode(定長), 統一用2Bytes代表一個字元, 雖然2**16-1=65535,但unicode卻可以存放100w+個字元,因為unicode存放了與其他編碼的對映關係,準確地說unicode並不是一種嚴格意義上的字元編碼表,下載pdf來檢視unicode的詳情: 連結:https://pan.baidu.com/s/1dEV3RYp 很明顯對於通篇都是英文的文字來說,unicode的式無疑是多了一倍的儲存空間(二進位制最終都是以電或者磁的方式儲存到儲存介質中的) 於是產生了UTF-8(可變長,全稱Unicode Transformation Format),對英文字元只用1Bytes表示,對中文字元用3Bytes,對其他生僻字用更多的Bytes去存 # 總結:記憶體中統一採用unicode,浪費空間來換取可以轉換成任意編碼(不亂碼),硬碟可以採用各種編碼,如utf-8,保證存放於硬碟或者基於網路傳輸的資料量很小,提高傳輸效率與穩定性。
重要

基於目前的現狀,記憶體中的編碼固定就是 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的形式了。

3)總結非常重要的兩點:

# 1,保證不亂嗎的核心法則就是,字元按照什麼標準而編碼的,就要按照什麼標準解碼,此處的標準指的就是字元編碼

# 2,在記憶體中寫的所有字元,一視同仁,都是unicode編碼,比如我們開啟編輯器,輸入一個“你”,我們並不能說“你”就是一個漢字,
# 此時它僅僅只是一個符號,該符號可能很多國家都在使用,根據我們使用的輸入法不同這個字的樣式可能也不太一樣。只有在我們往
# 硬碟儲存或者基於網路傳輸時,才能確定”你“到底是一個漢字,還是一個日本字,這就是unicode轉換成其他編碼格式的過程了

# 補充:
# 瀏覽網頁的時候,伺服器會把動態生成的Unicode內容轉換為UTF-8再傳輸到瀏覽器。

# 如果服務端encode的編碼格式是utf-8, 客戶端記憶體中收到的也是utf-8編碼的結果。