1. 程式人生 > >python3標準庫之反解析模組——dis module

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.Bytecodex*first_line = Nonecurrent_offset = None 

分析對應於函式,生成器,非同步生成器,協同程式,方法,原始碼字串或程式碼物件(由返回的compile())對應的位元組碼。

first_line不是None,則表示應該為反彙編程式碼中的第一個原始碼行報告的行號。否則,源行資訊(如果有的話)直接來自反彙編的程式碼物件。

current_offset不是None,則它指的是反彙編程式碼中的指令偏移量。設定此方法dis()將針對指定的操作碼顯示“當前指令”標記

(4)dis.dis(x=None*file=Nonedepth=None)

x物件反彙編成位元組碼。

 x可以表示模組,類,方法,函式,生成器,非同步生成器,協程,程式碼物件,原始碼串或原始位元組碼的位元組序列。

對於模組,它會反彙編所有功能。對於一個類,它會反彙編所有方法(包括類和靜態方法)。對於程式碼物件或原始位元組碼序列,它每位元組碼指令列印一行。它還遞迴地反彙編巢狀程式碼物件(理解程式碼,生成器表示式和巢狀函式,以及用於構建巢狀類的程式碼)。

compile()函式在被反彙編之前,字串首先被編譯為具有內建函式的程式碼物件。如果未提供任何物件,則此函式會反彙編最後一次回溯。如果提供,反彙編將作為文字寫入提供的檔案參引數sys.stdout。