1.內(nèi)存和硬盤都是用來存儲(chǔ)的斗遏。
內(nèi)存:速度快,臨時(shí)存放
硬盤:速度慢,永久保存
2.文本編輯器存取文件的原理(nodepad++,pycharm,word)
打開編輯器就可以啟動(dòng)一個(gè)進(jìn)程,是在內(nèi)存中的,所以在編輯器編寫的內(nèi)容也都是存放在內(nèi)存中的督勺,斷電后數(shù)據(jù)就丟失了。因而需要保存在硬盤上棍辕,點(diǎn)擊保存按鈕或快捷鍵舶沛,就把內(nèi)存中的數(shù)據(jù)保存到了硬盤上。在這一點(diǎn)上炮姨,我們編寫的py文件(沒有執(zhí)行時(shí))捌刮,跟編寫的其他文件沒有什么區(qū)別,都只是編寫一堆字符而已舒岸。
3.python解釋器執(zhí)行py文件的原理绅作,例如python test.py
第一階段: python解釋器啟動(dòng),此時(shí)就相當(dāng)于啟動(dòng)了一個(gè)文本編輯器
第二階段: python解釋器相當(dāng)于文本編輯器蛾派,去打開test.py俄认,從硬盤上將test.py的文件內(nèi)容讀入到內(nèi)存中
第三階段: python解釋器執(zhí)行剛剛加載到內(nèi)存中的test.py的代碼(在該階段,即執(zhí)行時(shí)洪乍,才會(huì)識(shí)別python的語法眯杏,執(zhí)行到字符串時(shí),會(huì)開辟內(nèi)存空間存放字符串)
總結(jié): python解釋器與文本編輯器的異同
相同點(diǎn): python解釋器是解釋執(zhí)行文件內(nèi)容的壳澳,因而python解釋器具備讀py文件的功能岂贩,這一點(diǎn)與文本編輯器一樣
不同點(diǎn): 文本編輯器將文件內(nèi)容讀入內(nèi)存后,是為了顯示/編輯巷波,而python解釋器將文件內(nèi)容讀入內(nèi)存后萎津,是為了執(zhí)行(識(shí)別python的語法)
4.什么是編碼卸伞?
計(jì)算機(jī)想要工作必須通電,高低電平(高電平即二進(jìn)制數(shù)1锉屈,低電平即二進(jìn)制數(shù)0)荤傲,也就是說計(jì)算機(jī)只認(rèn)識(shí)數(shù)字。那么讓計(jì)算機(jī)如何讀懂人類的字符呢?
這就必須經(jīng)過一個(gè)過程:
字符---------(翻譯過程)-------------數(shù)字
這個(gè)過程實(shí)際就是一個(gè)字符如何對(duì)應(yīng)一個(gè)特定數(shù)字的標(biāo)準(zhǔn)颈渊,這個(gè)標(biāo)準(zhǔn)稱之為字符編碼遂黍。
5.以下兩個(gè)場景涉及到字符編碼的問題:
1.一個(gè)python文件中的內(nèi)容是由一堆字符組成的(python文件未執(zhí)行時(shí))
2.python中的數(shù)據(jù)類型字符串是由一串字符組成的(python文件執(zhí)行時(shí))
6.字符編碼的發(fā)展史
階段一:現(xiàn)代計(jì)算機(jī)起源于美國,最早誕生也是基于英文考慮的ASCII
ASCII:一個(gè)Bytes代表一個(gè)字符(英文字符/鍵盤上的所有其他字符)俊嗽,1Bytes=8bit妓湘,8bit可以表示0-2*8-1種變化,即可以表示256個(gè)字符
ASCII最初只用了后七位乌询,127個(gè)數(shù)字榜贴,已經(jīng)完全能夠代表鍵盤上所有的字符了(英文字符/鍵盤的所有其他字符)
后來為了將拉丁文也編碼進(jìn)了ASCII表,將最高位也占用了
階段二:為了滿足中文妹田,中國人定制了GBK
GBK:2Bytes代表一個(gè)字符唬党,為了滿足其他國家,各個(gè)國家紛紛定制了自己的編碼鬼佣,日本把日文編到Shift_JIS里驶拱,韓國把韓文編到Euc-kr里
階段三:各國有各國的標(biāo)準(zhǔn),就會(huì)不可避免地出現(xiàn)沖突晶衷,結(jié)果就是蓝纲,在多語言混合的文本中,顯示出來會(huì)有亂碼晌纫。
于是產(chǎn)生了unicode税迷, 統(tǒng)一用2Bytes代表一個(gè)字符, 2*16-1=65535锹漱,可代表6萬多個(gè)字符箭养,因而兼容萬國語言
但對(duì)于通篇都是英文的文本來說,這種編碼方式無疑是多了一倍的存儲(chǔ)空間(二進(jìn)制最終都是以電或者磁的方式存儲(chǔ)到存儲(chǔ)介質(zhì)中的)
于是產(chǎn)生了UTF-8哥牍,對(duì)英文字符只用1Bytes表示毕泌,對(duì)中文字符用3Bytes
==需要強(qiáng)調(diào)的是:==
==unicode:== 簡單粗暴,多有的字符都是2Bytes,優(yōu)點(diǎn)是字符--數(shù)字的轉(zhuǎn)換速度快嗅辣;缺點(diǎn)是占用空間大撼泛。
==utf-8:== 精準(zhǔn),可變長澡谭,優(yōu)點(diǎn)是節(jié)省空間愿题;缺點(diǎn)是轉(zhuǎn)換速度慢,因?yàn)槊看无D(zhuǎn)換都需要計(jì)算出需要多長Bytes才能夠準(zhǔn)確表示。
- 1.內(nèi)存中使用的編碼是unicode抠忘,用空間換時(shí)間(程序都需要加載到內(nèi)存才能運(yùn)行,因而內(nèi)存應(yīng)該是越快越好)
- 2.硬盤中或網(wǎng)絡(luò)傳輸用utf-8外永,保證數(shù)據(jù)傳輸?shù)姆€(wěn)定性崎脉。
七、字符編碼轉(zhuǎn)換
unicode------>encode(編碼)-------->utf-8
utf-8---------->decode--------->unicode
文件從內(nèi)存刷到硬盤的操作簡稱存文件
文件從硬盤讀到內(nèi)存的操作簡稱讀文件
亂碼:存文件時(shí)就已經(jīng)亂碼 或者 存文件時(shí)不亂碼而讀文件時(shí)亂碼
總結(jié):
無論是何種編輯器伯顶,要防止文件出現(xiàn)亂碼(請(qǐng)一定注意囚灼,存放一段代碼的文件也僅僅只是一個(gè)普通文件而已,此處指的是文件沒有執(zhí)行前祭衩,我們打開文件時(shí)出現(xiàn)的亂碼)
核心法則就是灶体,文件以什么編碼保存的,就以什么編碼方式打開
八掐暮、 文本編輯器之python解釋器
文件test.py以gbk格式保存蝎抽,內(nèi)容為:
x='林'
無論是
python2 test.py
還是
python3 test.py
都會(huì)報(bào)錯(cuò)(因?yàn)閜ython2默認(rèn)ascii,python3默認(rèn)utf-8)
除非在文件開頭指定#coding:gbk
九路克、程序的執(zhí)行
python3 test.py 或 python2 test.py(執(zhí)行test.py的第一步樟结,一定是先將文件內(nèi)容讀入到內(nèi)存中)
階段一:啟動(dòng)python解釋器
階段二:python解釋器此時(shí)就是一個(gè)文本編輯器,負(fù)責(zé)打開文件test.py,即從硬盤中讀取test.py的內(nèi)容到內(nèi)存中
此時(shí)精算,python解釋器會(huì)讀取 test.py 的第一行內(nèi)容瓢宦,#coding :utf-8,來決定以什么編碼格式來讀入內(nèi)存,這一行就是來設(shè)定python解釋器這個(gè)軟件的編碼使用的編碼格式這個(gè)編碼灰羽,python2默認(rèn)使用ASCII驮履,python3中默認(rèn)使用utf-8
階段三:讀取已經(jīng)加載到內(nèi)存的代碼(unicode編碼的二進(jìn)制),然后執(zhí)行廉嚼,執(zhí)行過程中可能會(huì)開辟新的內(nèi)存空間玫镐,比如x="egon"
內(nèi)存的編碼使用unicode,不代表內(nèi)存中全都是unicode編碼的二進(jìn)制怠噪,
在程序執(zhí)行之前摘悴,內(nèi)存中確實(shí)都是unicode編碼的二進(jìn)制,比如從文件中讀取了一行x="egon",其中的x,等號(hào)舰绘,引號(hào)蹂喻,地位都一樣,都是普通字符而已捂寿,都是以u(píng)nicode編碼的二進(jìn)制形式存放與內(nèi)存中的
但是程序在執(zhí)行過程中口四,會(huì)申請(qǐng)內(nèi)存(與程序代碼所存在的內(nèi)存是倆個(gè)空間),可以存放任意編碼格式的數(shù)據(jù)秦陋,比如x="egon",會(huì)被python解釋器識(shí)別為字符串蔓彩,會(huì)申請(qǐng)內(nèi)存空間來存放"hello",然后讓x指向該內(nèi)存地址,此時(shí)新申請(qǐng)的該內(nèi)存地址保存也是unicode編碼的egon,如果代碼換成x="egon".encode('utf-8'),那么新申請(qǐng)的內(nèi)存空間里存放的就是utf-8編碼的字符串egon了
十赤嚼、python2與python3的區(qū)別
在python2中有兩種字符串類型str和unicode
在python2中旷赖,str就是編碼后的結(jié)果bytes,所以在Python2中更卒,unicode字符編碼的結(jié)果就是str/bytes
#coding:utf-8
s='林' #在執(zhí)行時(shí),'林'會(huì)被以conding:utf-8的形式保存到新的內(nèi)存空間中
print repr(s) #'\xe6\x9e\x97' 三個(gè)Bytes,證明確實(shí)是utf-8
print type(s) #<type 'str'>
s.decode('utf-8')
## s.encode('utf-8') #報(bào)錯(cuò)等孵,s為編碼后的結(jié)果bytes,所以只能decode
當(dāng)python解釋器執(zhí)行到產(chǎn)生字符串的代碼時(shí)(例如s=u'林')蹂空,會(huì)申請(qǐng)新的內(nèi)存地址俯萌,然后將'林'以u(píng)nicode的格式存放到新的內(nèi)存空間中,所以s只能encode上枕,不能decode
s=u'林'
print repr(s) #u'\u6797'
print type(s) #<type 'unicode'>
## s.decode('utf-8') #報(bào)錯(cuò)咐熙,s為unicode击蹲,所以只能encode
s.encode('utf-8')