python3標準庫之反解析模組——dis module
一、位元組碼
1、位元組碼是什麼。
python的原始檔是以.py結尾的,不知你是否見過或者聽說過以.pyc結尾的檔案,它儲存在__pycache__的資料夾中,這就是位元組碼。
2、位元組碼存在的作用。
python是解釋性語言,它在執行時將原始碼編譯成一組虛擬機器指令,並且Python 直譯器是針對相應的虛擬機器來實現的。為了避免每次執行程式時重新解析原始碼,同時能提高執行的速度,那麼這中間格式便存在了。
3、為什麼要了解位元組碼。
- 理解python的執行模型可以幫助理解我們的程式碼,更好地優化我們的程式碼。
- 理解位元組碼可以幫助理解python相關的問題,比如為什麼某些結構比其他結構執行速度更快。
- 理解面向棧的程式語言可以開拓我們的視野,豐富我們的知識。
二、CPython
CPython是用C語言編寫的python直譯器,CPython是使用位元組碼的直譯器,任何程式原始碼在執行之前先要編譯生成位元組碼。
CPython是使用一種基於棧的虛擬機器,它完全面向棧資料結構。
2、CPython的型別。
- 呼叫棧:執行python程式的主要結構,每個當前活動的函式呼叫使用了一個叫“幀”的東西,每個函式呼叫推送一個新的幀到呼叫幀,並且在函式呼叫結束後銷燬幀。
- 計算幀(資料幀):python函式執行的地方 ,執行的python程式碼大多推入這個棧,操作完成之後銷燬它們。
- 塊幀:python用於跟蹤某些型別的資料結構,如迴圈、try/except塊、with塊,執行時這些塊將會被推入棧中,執行完成之後銷燬它們,但是continue/break會影響它們的正常執行。
三、dis模組(參考python官方文件)
dis模組支援通過反彙編分析位元組碼,該該模組作為輸入的CPython位元組碼在檔案中定義,Include/opcode.h
並由編譯器和直譯器使用。
1、通過dis模組簡單演示反彙編並分析。
最左邊的數字2是編譯該位元組程式碼的原始碼中的行號。左邊列中的數字是位元組碼中指令的偏移量,右邊的數字是oparg
(1)class dis.
Bytecode
(x,*,first_line = None,current_offset = None )
分析對應於函式,生成器,非同步生成器,協同程式,方法,原始碼字串或程式碼物件(由返回的compile())對應的位元組碼。
first_line不是None,則表示應該為反彙編程式碼中的第一個原始碼行報告的行號。否則,源行資訊(如果有的話)直接來自反彙編的程式碼物件。
current_offset不是None
,則它指的是反彙編程式碼中的指令偏移量。設定此方法dis()
將針對指定的操作碼顯示“當前指令”標記
(4)dis.
dis
(x=None, *, file=None, depth=None)
將x物件反彙編成位元組碼。
x可以表示模組,類,方法,函式,生成器,非同步生成器,協程,程式碼物件,原始碼串或原始位元組碼的位元組序列。
對於模組,它會反彙編所有功能。對於一個類,它會反彙編所有方法(包括類和靜態方法)。對於程式碼物件或原始位元組碼序列,它每位元組碼指令列印一行。它還遞迴地反彙編巢狀程式碼物件(理解程式碼,生成器表示式和巢狀函式,以及用於構建巢狀類的程式碼)。
compile()函式在被反彙編之前,字串首先被編譯為具有內建函式的程式碼物件。如果未提供任何物件,則此函式會反彙編最後一次回溯。如果提供,反彙編將作為文字寫入提供的檔案參引數sys.stdout。