<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
開啟編輯器就開啟了啟動了一個程序,是在記憶體中的,所以在編輯器編寫的內容也都是存放與記憶體中的,斷電後資料丟失,因而需要儲存到硬碟上,點選儲存按鈕,就從記憶體中把資料刷到了硬碟上。在這一點上,我們編寫一個py檔案(沒有執行),跟編寫其他檔案沒有任何區別,都只是在編寫一堆字元而已。
即:在沒有點選儲存時,我們所寫的內容都是寫入記憶體。注意這一點,很重要!!當我們點選儲存,內容才被刷到硬碟。
上面做了兩件事:寫內容到記憶體,從記憶體將記憶體刷到硬碟。這是兩個過程。
例如:python test.py
python直譯器執行py檔案分為兩個步驟:1.將檔案讀到記憶體,2.解釋執行內容。
要搞清楚字元編碼,首先要解決的問題是:什麼是字元編碼?
我們都知道,計算機要想工作必須通電,也就是說‘電’驅使計算機幹活,而‘電’的特性,就是高低電平(高低平即二進位制數1,低電平即二進位制數0),也就是說計算機只認識數位(010101).如果我們想儲存資料,首先得將我們的資料進行一些處理,最終得轉換成010101才能讓計算機識別。
所以必須經過一個過程:
字元--------(翻譯過程)------->數位
這個過程實際就是一個字元如何對應一個特定數位的標準,這個標準稱之為字元編碼。
那麼問題就來了?作為一種編碼方案,還得解決兩個問題:
ASCII碼是上個世紀最流行的編碼體系之一,至少在西方是這樣。下圖顯示了ASCII碼中編碼單元是怎麼對映到字元上的。
階段一:現代計算機起源於美國,最早誕生也是基於英文考慮的ASCII
隨著計算機越來越流行,廠商之間的競爭更加激烈,在不同的計算機體系間轉換資料變得十分蛋疼,人們厭煩了這種自定義造成的混亂。最終,計算機制造商一起制定了一個標準的方法來描述字元。他們定義使用一個位元組的低7位來表示字元,並且製作瞭如上圖所示的對照表來對映七個位元的值到一個字元上。例如,字母A是65,c是99,~是126等等, ASCII碼就這樣誕生了。原始的ASCII標準定義了從0到127 的字元,這樣正好能用七個位元表示。
為什麼選擇了7個位元而不是8個來表示一個字元呢?我並不關心。但是一個位元組是8個位元,這意味著1個位元並沒有被使用,也就是從128到255的編碼並沒有被制定ASCII標準的人所規定,這些美國人對世界的其它地方一無所知甚至完全不關心。其它國家的人趁這個機會開始使用128到255範圍內的編碼來表達自己語言中的字元。例如,144在阿拉伯人的ASCII碼中是گ,而在俄羅斯的ASCII碼中是ђ。ASCII碼的問題在於儘管所有人都在0-127號字元的使用上達成了一致,但對於128-255號字元卻有很多很多不同的解釋。你必須告訴計算機使用哪種風格的ASCII碼才能正確顯示128-255號的字元。
總結:ASCII,一個Bytes代表一個字元(英文字元/鍵盤上的所有其他字元),1Bytes=8bit,8bit可以表示0-2**8-1種變化,即可以表示256個字元,ASCII最初只用了後七位,127個數位,已經完全能夠代表鍵盤上所有的字元了(英文字元/鍵盤的所有其他字元),後來為了將拉丁文也編碼進了ASCII表,將最高位也佔用了。
階段二:為了滿足中文,中國人客製化了GBK
GBK:2Bytes代表一個字元;為了滿足其他國家,各個國家紛紛客製化了自己的編碼。日本把日文編到Shift_JIS裡,韓國把韓文編到Euc-kr裡
階段三:萬國碼Unicode
編碼
後來,有人開始覺得太多編碼導致世界變得過於複雜了,讓人腦袋疼,於是大家坐在一起拍腦袋想出來一個方法:所有語言的字元都用同一種字元集來表示,這就是Unicode。
Unicode統一用2Bytes代表一個字元,2**16-1=65535
,可代表6萬多個字元,因而相容萬國語言.但對於通篇都是英文的文字來說,這種編碼方式無疑是多了一倍的儲存空間(英文字母只需要一個位元組就足夠,用兩個位元組來表示,無疑是浪費空間).於是產生了UTF-8,對英文字元只用1Bytes表示,對中文字元用3Bytes.UTF-8
是一個非常驚豔的概念,它漂亮的實現了對ASCII碼的向後相容,以保證Unicode可以被大眾接受。
在UTF-8中,0-127號的字元用1個位元組來表示,使用和US-ASCII相同的編碼。這意味著1980年代寫的檔案用UTF-8開啟一點問題都沒有。只有128號及以上的字元才用2個,3個或者4個位元組來表示。因此,UTF-8被稱作可變長度編碼。
於是位元組流:0100100001000101010011000100110001001111
這個位元組流在ASCII和UTF-8中表示相同的字元:HELLO
至於其他的UTF-16,這裡就不再敘述了。
總結一點:unicode:簡單粗暴,所有字元都是2Bytes,優點是字元----->數位的轉換速度快,缺點是佔用空間大。
utf-8:精準,對不同的字元用不同的長度表示,優點是節省空間,缺點是:字元->數位的轉換速度慢,因為每次都需要計算出字元需要多長的Bytes才能夠準確表示。
因此,記憶體中使用的編碼是unicode,用空間換時間(程式都需要載入到記憶體才能執行,因而記憶體應該是儘可能的保證快);硬碟中或者網路傳輸用utf-8,網路I/O延遲或磁碟I/O延遲要遠大與utf-8的轉換延遲,而且I/O應該是儘可能地節省頻寬,保證資料傳輸的穩定性。
所有程式,最終都要載入到記憶體,程式儲存到硬碟不同的國家用不同的編碼格式,但是到記憶體中我們為了相容萬國(計算機可以執行任何國家的程式原因在於此),統一且固定使用unicode,這就是為何記憶體固定用unicode的原因,你可能會說相容萬國我可以用utf-8啊,可以,完全可以正常工作,之所以不用肯定是unicode比utf-8
更高效啊(uicode固定用2個位元組編碼,utf-8則需要計算),但是unicode更浪費空間,沒錯,這就是用空間換時間的一種做法,而存放到硬碟,或者網路傳輸,都需要把unicode
轉成utf-8
,因為資料的傳輸,追求的是穩定,高效,資料量越小資料傳輸就越靠譜,於是都轉成utf-8格式的,而不是unicode。
不管是哪種型別的檔案,只要記住一點:檔案以什麼編碼儲存的,就以什麼編碼方式開啟.
下面我們來看看python中關於編碼出現的問題:
如果不在python檔案指定頭資訊#-*-coding:utf-8-*-
,那就使用預設的python2中預設使用ascii,python3中預設使用utf-8
讀取已經載入到記憶體的程式碼(unicode編碼的二進位制),然後執行,執行過程中可能會開闢新的記憶體空間,比如x="hello"
記憶體的編碼使用unicode,不代表記憶體中全都是unicode編碼的二進位制,在程式執行之前,記憶體中確實都是unicode編碼的二進位制,比如從檔案中讀取了一行x="hello"
,其中的x,等號,引號,地位都一樣,都是普通字元而已,都是以unicode編碼的二進位制形式存放與記憶體中的.但是程式在執行過程中,會申請記憶體(與程式程式碼所存在的記憶體是倆個空間),可以存放任意編碼格式的資料,比如x="hello",會被python直譯器識別為字串,會申請記憶體空間來存放"hello",然後讓x指向該記憶體地址,此時新申請的該記憶體地址儲存也是unicode編碼的hello,如果程式碼換成x="hello".encode('utf-8')
,那麼新申請的記憶體空間裡存放的就是utf-8編碼的字串hello了.
瀏覽網頁的時候,伺服器會把動態生成的Unicode內容轉換為UTF-8再傳輸到瀏覽器
如果伺服器端encode的編碼格式是utf-8, 使用者端記憶體中收到的也是utf-8編碼的二進位制
str型別:
當python直譯器執行到產生字串的程式碼時(例如s='林'),會申請新的記憶體地址,然後將'林'編碼成檔案開頭指定的編碼格式,這已經是encode之後的結果了,所以s只能decode。再次encode就會報錯。
#_*_coding:gbk_*_ 2 #!/usr/bin/env python 3 4 x='林' 5 # print x.encode('gbk') #報錯 6 print x.decode('gbk') #結果:林
在python2中,str就是編碼後的結果bytes,str=bytes,所以在python2中,unicode字元編碼的結果是str/bytes。
#coding:utf-8 s='林' #在執行時,'林'會被以conding:utf-8的形式儲存到新的記憶體空間中 print repr(s) #'xe6x9ex97' 三個Bytes,證明確實是utf-8 print 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,所以只能encode s.encode('utf-8')
特別說明:
當資料要列印到終端時,要注意一些問題.
當程式執行時,比如:x='林';print(x) #這一步是將x指向的那塊新的記憶體空間(非程式碼所在的記憶體空間)中的記憶體,列印到終端,而終端仍然是執行於記憶體中的,所以這列印可以理解為從記憶體列印到記憶體,即記憶體->記憶體,unicode->unicode.對於unicode格式的資料來說,無論怎麼列印,都不會亂碼.python3中的字串與python2中的u'字串',都是unicode,所以無論如何列印都不會亂碼.在windows終端(終端編碼為gbk,檔案編碼為utf-8,亂碼產生)
#分別驗證在pycharm中和cmd中下述的列印結果 s=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) #'xe6x9ex97' 編碼一個漢字utf-8用3Bytes print repr(s2) #'xc1xd6' 編碼一個漢字gbk用2Bytes print type(s) #<type 'unicode'> print type(s1) #<type 'str'> print type(s2) #<type 'str'>
str型別變為unicode型別:
#coding:utf-8 s='林' #當程式執行時,無需加u,'林'也會被以unicode形式儲存新的記憶體空間中, #s可以直接encode成任意編碼格式 s.encode('utf-8') s.encode('gbk') print(type(s)) #<class 'str'>
bytes型別:
#coding:utf-8 s='林' #當程式執行時,無需加u,'林'也會被以unicode形式儲存新的記憶體空間中, #s可以直接encode成任意編碼格式 s1=s.encode('utf-8') s2=s.encode('gbk') print(s) #林 print(s1) #b'xe6x9ex97' 在python3中,是什麼就列印什麼 print(s2) #b'xc1xd6' 同上 print(type(s)) #<class 'str'> print(type(s1)) #<class 'bytes'> print(type(s2)) #<class 'bytes'>
到此這篇關於python編碼問題彙總的文章就介紹到這了,更多相關python編碼內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45