python之什么是字節(jié)碼(bytecode)?
簡(jiǎn)單的說(shuō)它就是一個(gè)從源代碼編譯而來(lái)的中間文件(用于不同操作系統(tǒng)平臺(tái)的解釋器執(zhí)行)。比如,a說(shuō)日語(yǔ),b說(shuō)中文,溝通起來(lái)不暢通,請(qǐng)一個(gè)翻譯,把a(bǔ)和b的語(yǔ)言都翻譯成英語(yǔ),這個(gè)英語(yǔ)就可以理解成bytecode,一種中間語(yǔ)言。
bytecode的好處就是加載快,而且可以跨平臺(tái),同樣一份bytecode,只要有操作系統(tǒng)平臺(tái)上有相應(yīng)的Python解釋器,就可以執(zhí)行,而不需要源代碼。不同版本的Python編譯的字節(jié)碼是不兼容的,Python2.6編譯的bytecode拿到Python2.7上去執(zhí)行就不行了。
如何生成字節(jié)碼?
Python解釋器一般會(huì)自動(dòng)把.py文件轉(zhuǎn)換成bytecode,然后再執(zhí)行它。當(dāng)你第一次把.py文件當(dāng)作module導(dǎo)入,或者對(duì)應(yīng)的.py文件比.pyc文件的修改時(shí)間還要新時(shí),Python解釋器都會(huì)再?gòu)膕ourcecode生成相應(yīng)的新bytecode。這樣當(dāng)你下次再次運(yùn)行程序時(shí),就會(huì)直接從bytecode運(yùn)行,從而節(jié)省便宜時(shí)間。
Ps:這里需要注意,有些情況bytecode并不會(huì)生成:
遇到目錄寫權(quán)限的問(wèn)題時(shí)。(比如你編寫代碼和運(yùn)行代碼使用的具有不同權(quán)限的用戶角色,Linux上很常見)
運(yùn)行一個(gè)script并不會(huì)被當(dāng)成是import操作,所以可能也不會(huì)生成bytecode。(比如:你有個(gè)一個(gè)a.py的文件,其中在a.py里,你import了b.py,那么運(yùn)行pythona.py后,會(huì)生成b.pyc,而不會(huì)生成a.pyc)
.pyc文件是什么?
Python源碼編譯的結(jié)果就是PyCodeObject,每個(gè)作用域會(huì)編譯出一個(gè)對(duì)應(yīng)的代碼對(duì)象,其中名為co_code的PyStringObject保存著代碼對(duì)象的字節(jié)碼。
一個(gè)Python源文件就是一個(gè)模塊。每個(gè)模塊頂層的代碼對(duì)象通過(guò)marshal序列化之后就得到了.pyc文件。marshal以little-endian字節(jié)序來(lái)序列化數(shù)據(jù)。
那嵌套于頂層作用域里面的那些作用域,例如函數(shù)、類的定義,它們對(duì)應(yīng)的代碼對(duì)象在哪里?它們每一個(gè)都乖乖的躺在上一層作用域的代碼對(duì)象的co_const(常量池)域里,所以其實(shí)頂層代碼對(duì)象已經(jīng)嵌套包含了底下其它作用域的代碼對(duì)象。
如何對(duì).pyc文件文件進(jìn)行反編譯?
python文件如果要發(fā)布的話,有時(shí)候還是難免想保護(hù)一下自己的源碼,有些人就直接編譯成了pyc文件,因?yàn)檫@樣既可以保留跨平臺(tái)的特性,又可以不能直接看到代碼,也看到網(wǎng)上很多人說(shuō)為了保護(hù)自己的代碼可以編譯成pyc文件。
用pyc文件可以保護(hù)python代碼的想法其實(shí)是不正確的,pyc文件是可以很容易被反編譯的,比如說(shuō)比較著名的uncompyle6庫(kù)(https://github.com/rocky/python-uncompyle6),用來(lái)反編譯文件最爽不過(guò)了,幾乎支持python全版本的pyc文件的反編譯。
為什么要做代碼分析?
一般來(lái)說(shuō),代碼分析重要性的判斷比較主觀,不同的人有不同的認(rèn)識(shí)。Python是用C來(lái)實(shí)現(xiàn)的,所以對(duì)于Python的性能或代碼質(zhì)量的評(píng)估可以通過(guò)dis模塊獲取到對(duì)應(yīng)的字節(jié)碼指令來(lái)進(jìn)行評(píng)估。
一般來(lái)說(shuō)一個(gè)Python語(yǔ)句會(huì)對(duì)應(yīng)若干字節(jié)碼指令,Python的字節(jié)碼是一種類似匯編指令的中間語(yǔ)言,但是一個(gè)字節(jié)碼指令并不是對(duì)應(yīng)一個(gè)機(jī)器指令(二進(jìn)制指令),而是對(duì)應(yīng)一段C代碼,而不同的指令的性能不同,所以不能單獨(dú)通過(guò)指令數(shù)量來(lái)判斷代碼的性能,而是要通過(guò)查看調(diào)用比較頻繁的指令的代碼來(lái)確認(rèn)一段程序的性能。
一個(gè)Python的程序會(huì)有若干代碼塊組成,例如一個(gè)Python文件會(huì)是一個(gè)代碼塊,一個(gè)類,一個(gè)函數(shù)都是一個(gè)代碼塊,一個(gè)代碼塊會(huì)對(duì)應(yīng)一個(gè)運(yùn)行的上下文環(huán)境以及一系列的字節(jié)碼指令。
dis模塊主要是用來(lái)分析字節(jié)碼的一個(gè)內(nèi)置模塊。dis模塊的文檔可以讓你遍歷它的內(nèi)容,并且提供一個(gè)字節(jié)碼指令能夠做什么和有什么樣的參數(shù)的完整清單。
以上內(nèi)容為大家介紹了python之什么是字節(jié)碼(bytecode)?希望對(duì)大家有所幫助,如果想要了解更多Python相關(guān)知識(shí),請(qǐng)關(guān)注IT培訓(xùn)機(jī)構(gòu):千鋒教育。http://www.mobiletrain.org/

猜你喜歡LIKE
相關(guān)推薦HOT
更多>>
pythonfor循環(huán)是什么
pythonfor循環(huán)是什么在做遍歷的時(shí)候,對(duì)于一些數(shù)據(jù)的反復(fù)循環(huán)執(zhí)行,我們會(huì)用到for循環(huán)的語(yǔ)句。可以說(shuō)這是新手入門必學(xué)的語(yǔ)句之一,在很多基礎(chǔ)循...詳情>>
2023-11-13 07:46:36
pythoncontextmanager()的轉(zhuǎn)換
python中contextmanager()的轉(zhuǎn)換1、說(shuō)明當(dāng)發(fā)出請(qǐng)求時(shí),requests庫(kù)會(huì)在將請(qǐng)求實(shí)際發(fā)送到目標(biāo)服務(wù)器之前準(zhǔn)備該請(qǐng)求。請(qǐng)求準(zhǔn)備包括像驗(yàn)證頭信息和...詳情>>
2023-11-13 06:34:35
python使用items()遍歷鍵值對(duì)
python使用items()遍歷鍵值對(duì)字典可以用來(lái)存儲(chǔ)各種方式的信息,所以有很多方式可以通過(guò)字典的所有鍵值對(duì)、鍵或值。說(shuō)明1、即使通過(guò)字典,鍵值對(duì)...詳情>>
2023-11-13 04:24:15
python實(shí)例方法中self的作用
python實(shí)例方法中self的作用說(shuō)明1、無(wú)論是創(chuàng)建類的構(gòu)造方法還是實(shí)例方法,最少要包含一個(gè)參數(shù)self。2、通過(guò)實(shí)例的self參數(shù)與對(duì)象進(jìn)行綁定,程序...詳情>>
2023-11-13 03:46:48熱門推薦
python實(shí)現(xiàn)WSGI的框架
沸pythonfor循環(huán)是什么
熱python-=是什么意思
熱python打開文本文件有哪些方法?
新pythoncontextmanager()的轉(zhuǎn)換
pythonre是什么?
pythondecimal是什么
python列表追加元素出錯(cuò)的解決
python使用loguru操作日志
python使用items()遍歷鍵值對(duì)
pythonvim中有哪些對(duì)象
python實(shí)例方法中self的作用
pythonin和is的區(qū)分
pythonos.path.join()函數(shù)的使用
技術(shù)干貨







快速通道 更多>>
-
課程介紹
點(diǎn)擊獲取大綱 -
就業(yè)前景
查看就業(yè)薪資 -
學(xué)習(xí)費(fèi)用
了解課程價(jià)格 -
優(yōu)惠活動(dòng)
領(lǐng)取優(yōu)惠券 -
學(xué)習(xí)資源
領(lǐng)3000G教程 -
師資團(tuán)隊(duì)
了解師資團(tuán)隊(duì) -
實(shí)戰(zhàn)項(xiàng)目
獲取項(xiàng)目源碼 -
開班地區(qū)
查看來(lái)校路線