Python(字元編碼)

來源:互聯網
上載者:User

標籤:證明   不能   python3   test   特性   toolbar   default   額外   pre   

https://www.cnblogs.com/zihe/p/6993891.html一 瞭解字元編碼的知識儲備

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

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

             因而需要儲存到硬碟上,點擊儲存按鈕,就從記憶體中把資料刷到了硬碟上。

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

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

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

    第二階段:python解譯器相當於文字編輯器,去開啟test.py檔案,從硬碟上將test.py的檔案內容讀入到記憶體中

    第三階段:python解譯器解釋執行剛剛載入到記憶體中test.py的代碼  

  總結:

  1. python解譯器是解釋執行檔案內容的,因而python解譯器具備讀py檔案的功能,這一點與文字編輯器一樣
  2. 與文字編輯器不一樣的地方在於,python解譯器不僅可以讀檔案內容,還可以執行檔案內容
二 什麼是字元編碼

  電腦要想工作必須通電,也就是說‘電’驅使電腦幹活,而‘電’的特性,就是高低電平(高低平即位元1,低電平即位元0),也就是說電腦只認識數字 

  編程的目的是讓電腦幹活,而編程的結果說白了只是一堆字元,也就是說我們編程最終要實現的是:一堆字元驅動電腦幹活

  所以必須經過一個過程:

  字元--------(翻譯過程)------->數字 

  這個過程實際就是一個字元如何對應一個特定數位標準,這個標準稱之為字元編碼

三 字元編碼的發展史

階段一:現代電腦起源於美國,最早誕生也是基於英文考慮的ASCII

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

    ASCII最初只用了後七位,127個數字,已經完全能夠代表鍵盤上所有的字元了(英文字元/鍵盤的所有其他字元)

    後來為了將拉丁文也編碼進了ASCII表,將最高位也佔用了

階段二:為了滿足中文,中國人定製了GBK

  GBK:2Bytes代表一個字元

  為了滿足其他國家,各個國家紛紛定製了自己的編碼

  日本把日文編到Shift_JIS裡,韓國把韓文編到Euc-kr

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

於是產生了unicode, 統一用2Bytes代表一個字元, 2**16-1=65535,可代表6萬多個字元,因而相容萬國語言

但對於通篇都是英文的文本來說,這種編碼方式無疑是多了一倍的儲存空間(二進位最終都是以電或者磁的方式儲存到儲存介質中的)

於是產生了UTF-8,對英文字元只用1Bytes表示,對中文字元用3Bytes

需要強調的一點是:

unicode:簡單粗暴,所有字元都是2Bytes,優點是字元->數位轉換速度快,缺點是佔用空間大

utf-8:精準,對不同的字元用不同的長度表示,優點是節省空間的,缺點是:字元->數位轉換速度慢,因為每次都需要計算出字元需要多長的Bytes才能夠準確表示

  1. 記憶體中使用的編碼是unicode,用空間換時間(程式都需要載入到記憶體才能運行,因而記憶體應該是儘可能的保證快)
  2. 硬碟中或者網路傳輸用utf-8,網路I/O延遲或磁碟I/O延遲要遠大與utf-8的轉換延遲,而且I/O應該是儘可能地節省頻寬,保證資料轉送的穩定性。

 

四.字元編碼分類

電腦由美國人發明,最早的字元編碼為ASCII,只規定了英文字母數字和一些特殊字元與數位對應關係。

ascii用1個位元組(8位二進位)代表一個字元

unicode常用2個位元組(16位二進位)代表一個字元,生僻字需要用4個位元組

如果我們的文檔通篇都是英文,你用unicode會比ascii耗費多一倍的空間,在儲存和傳輸上十分的低效

本著節約的精神,又出現了把Unicode編碼轉化為“可變長編碼”的UTF-8編碼。UTF-8編碼把一個Unicode字元根據不同的數字大小編碼成1-6個位元組,常用的英文字母被編碼成1個位元組,漢字通常是3個位元組,只有很生僻的字元才會被編碼成4-6個位元組。如果你要傳輸的文本包含大量英文字元,用UTF-8編碼就能節省空間的:

字元 ASCII Unicode UTF-8
A 01000001 00000000 01000001 01000001
x 01001110 00101101 11100100 10111000 10101101

從上面的表格還可以發現,UTF-8編碼有一個額外的好處,就是ASCII編碼實際上可以被看成是UTF-8編碼的一部分,所以,大量只支援ASCII編碼的曆史遺留軟體可以在UTF-8編碼下繼續工作。

五 字元編碼的使用5.1 文字編輯器一鍋端

 

5.1.2 文字編輯器nodpad++

總結:

無論是何種編輯器,要防止檔案出現亂碼(請一定注意,存放一段代碼的檔案也僅僅只是一個普通檔案而已,此處指的是檔案沒有執行前,我們開啟檔案時出現的亂碼)

核心法則就是,檔案以什麼編碼儲存的,就以什麼編碼方式開啟

而檔案編碼儲存時候使用的編碼方式是右下角的編碼方式,而解碼的時候是使用文檔開頭申明的編碼方式,兩種編碼不同的時候很容易出現亂碼的情況。

 

5.2 程式的執行

python test.py   (我再強調一遍,執行test.py的第一步,一定是先將檔案內容讀入到記憶體中)

 

階段一:啟動python解譯器

階段二:python解譯器此時就是一個文字編輯器,負責開啟檔案test.py,即從硬碟中讀取test.py的內容到記憶體中

此時,python解譯器會讀取test.py的第一行內容,#coding:utf-8,來決定以什麼編碼格式來讀入記憶體,這一行就是來設定python解譯器這個軟體的編碼使用的編碼格式這個編碼,

可以用sys.getdefaultencoding()查看,如果不在python檔案指定頭資訊#-*-coding:utf-8-*-,那就使用預設的

python2中預設使用ascii,python3中預設使用utf-8

 

 

 

階段三:讀取已經載入到記憶體的代碼(unicode編碼的二進位),然後執行,執行過程中可能會開闢新的記憶體空間,比如x="egon"

記憶體的編碼使用unicode,不代表記憶體中全都是unicode編碼的二進位,

在程式執行之前,記憶體中確實都是unicode編碼的二進位,比如從檔案中讀取了一行x="egon",其中的x,等號,引號,地位都一樣,都是一般字元而已,都是以unicode編碼的二進位形式存放與記憶體中的

但是程式在執行過程中,會申請記憶體(與程式碼所存在的記憶體是倆個空間),可以存放任意編碼格式的資料,比如x="egon",會被python解譯器識別為字串,會申請記憶體空間來存放"hello",然後讓x指向該記憶體位址,此時新申請的該記憶體位址儲存也是unicode編碼的egon,如果代碼換成x="egon".encode(‘utf-8‘),那麼新申請的記憶體空間裡存放的就是utf-8編碼的字串egon了

針對python3如

 

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

 

如果服務端encode的編碼格式是utf-8, 用戶端記憶體中收到的也是utf-8編碼的二進位。

 

5.3 python2與python3的區別 5.3.1 在python2中有兩種字串類型str和unicode

str類型

當python解譯器執行到產生字串的代碼時(例如s=‘林‘),會申請新的記憶體位址,然後將‘林‘encode成檔案開頭指定的編碼格式,這已經是encode之後的結果了,所以s只能decode

1 #_*_coding:gbk_*_2 #!/usr/bin/env python3 4 x=‘林‘5 # print x.encode(‘gbk‘) #報錯6 print x.decode(‘gbk‘) #結果:林

 

所以很重要的一點是:

在python2中,str就是編碼後的結果bytes,str=bytes,所以在python2中,unicode字元編碼的結果是str/bytes

 

#coding:utf-8s=‘林‘ #在執行時,‘林‘會被以conding:utf-8的形式儲存到新的記憶體空間中print repr(s) #‘\xe6\x9e\x97‘ 三個Bytes,證明確實是utf-8print type(s) #<type ‘str‘>s.decode(‘utf-8‘)# s.encode(‘utf-8‘) #報錯,s為編碼後的結果bytes,所以只能decode

 

unicode類型

當python解譯器執行到產生字串的代碼時(例如s=u‘林‘),會申請新的記憶體位址,然後將‘林‘以unicode的格式存放到新的記憶體空間中,所以s只能encode,不能decode

s=u‘林‘print repr(s) #u‘\u6797‘print type(s) #<type ‘unicode‘># s.decode(‘utf-8‘) #報錯,s為unicode,所以只能encodes.encode(‘utf-8‘) 

列印到終端

對於print需要特別說明的是:

當程式執行時,比如

x=‘林‘

print(x) #這一步是將x指向的那塊新的記憶體空間(非代碼所在的記憶體空間)中的記憶體,列印到終端,而終端仍然是運行於記憶體中的,所以這列印可以理解為從記憶體列印到記憶體,即記憶體->記憶體,unicode->unicode

 

對於unicode格式的資料來說,無論怎麼列印,都不會亂碼

python3中的字串與python2中的u‘字串‘,都是unicode,所以無論如何列印都不會亂碼

在pycharm中

在windows終端

 

 

但是在python2中存在另外一種非unicode的字串,此時,print x,會按照終端的編碼執行x.decode(‘終端編碼‘),變成unicode後,再列印,此時終端編碼若與檔案開頭指定的編碼不一致,亂碼就產生了

在pycharm中(終端編碼為utf-8,檔案編碼為utf-8,不會亂碼)

 

在windows終端(終端編碼為gbk,檔案編碼為utf-8,亂碼產生)

 

 

 

思考題:

分別驗證在pycharm中和cmd中下述的列印結果

#coding:utf-8s=u‘林‘ #當程式執行時,‘林‘會被以unicode形式儲存新的記憶體空間中#s指向的是unicode,因而可以編碼成任意格式,都不會報encode錯誤s1=s.encode(‘utf-8‘)s2=s.encode(‘gbk‘)print s1 #列印正常否?print s2 #列印正常否print repr(s) #u‘\u6797‘print repr(s1) #‘\xe6\x9e\x97‘ 編碼一個漢字utf-8用3Bytesprint repr(s2) #‘\xc1\xd6‘ 編碼一個漢字gbk用2Bytesprint type(s) #<type ‘unicode‘>print type(s1) #<type ‘str‘>print type(s2) #<type ‘str‘>

 

5.3.2 在python3中也有兩種字串類型str和bytes

str是unicode

#coding:utf-8s=‘林‘ #當程式執行時,無需加u,‘林‘也會被以unicode形式儲存新的記憶體空間中,#s可以直接encode成任意編碼格式s.encode(‘utf-8‘)s.encode(‘gbk‘)print(type(s)) #<class ‘str‘>

 

bytes是bytes

#coding:utf-8s=‘林‘ #當程式執行時,無需加u,‘林‘也會被以unicode形式儲存新的記憶體空間中,#s可以直接encode成任意編碼格式s1=s.encode(‘utf-8‘)s2=s.encode(‘gbk‘)print(s) #林print(s1) #b‘\xe6\x9e\x97‘ 在python3中,是什麼就列印什麼print(s2) #b‘\xc1\xd6‘ 同上print(type(s)) #<class ‘str‘>print(type(s1)) #<class ‘bytes‘>print(type(s2)) #<class ‘bytes‘>

 

Python(字元編碼)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.