python中的dis剖析原始碼及引數含義的講解
阿新 • • 發佈:2019-02-02
Python 程式碼先被編譯為位元組碼後,再由Python虛擬機器來執行位元組碼, Python的位元組碼是一種類似彙編指令的中間語言, 一個Python語句會對應若干位元組碼指令,虛擬機器一條一條執行位元組碼指令, 從而完成程式執行。
Python dis 模組支援對Python程式碼進行反彙編, 生成位元組碼指令。
先來一小段程式碼:
Python程式碼在編譯過程中會生成CodeObject, CodeObject是在虛擬機器中的抽象表示, 在Python C原始碼中表示為PyCodeObject, 而生成的.pyc 檔案則是位元組碼在磁碟中的表現形式。以Python程式碼為講,test.__code__.co_code 表示test函式的位元組碼指令序列。
將此序列打印出來,
可以通過dis.opname[100]檢視,即為LOAD_CONST。而後的兩個位元組表示指令的引數。而dis輸出的位元組碼指令中,
第二列的位元組碼索引則是指當前指令在co_code序列中所在的位置。
dis輸出的位元組碼指令中,部分指令是沒有引數, 在co_code 中也同樣可以看到,83(RETURN_VALUE)直接接上下一條指令100(LOAD_CONST)。
Python dis 模組支援對Python程式碼進行反彙編, 生成位元組碼指令。
先來一小段程式碼:
- In[6]: def test():
- ... x = 1
- ... if x < 3:
- ... return"yes"
- ... else:
- ... return"no"
- In[7]: import dis
- In[8]: dis.dis(test)
- 20 LOAD_CONST 1 (1)
- 3 STORE_FAST 0 (x)
- 36 LOAD_FAST 0 (x)
- 9 LOAD_CONST 2 (3)
- 12 COMPARE_OP 0 (<)
- 15 POP_JUMP_IF_FALSE
- 418 LOAD_CONST 3 ('yes')
- 21 RETURN_VALUE
- 6 >> 22 LOAD_CONST 4 ('no')
- 25 RETURN_VALUE
- 26 LOAD_CONST 0 (None)
- 29 RETURN_VALUE
以第一條指令為例, 第一列的數字(2)表示對應原始碼的行數。第二列的數字是位元組碼的索引,指令LOAD_CONST在0位置。第三列是指令本身對應的人類可讀的名字。第四列表示指令的引數。第5列則是計算後的實際引數。其中的“>>" 表示跳轉的目標, 第4列的“22” 表明了跳轉到索引為22的指令。
Python程式碼在編譯過程中會生成CodeObject, CodeObject是在虛擬機器中的抽象表示, 在Python C原始碼中表示為PyCodeObject, 而生成的.pyc 檔案則是位元組碼在磁碟中的表現形式。以Python程式碼為講,test.__code__.co_code 表示test函式的位元組碼指令序列。
將此序列打印出來,
- code = [ord(i) for i in list(test.__code__.co_code)]
- print code
- [100, 1, 0, 125, 0, 0, 124, 0, 0, 100, 2, 0, 107, 0, 0, 114, 22, 0, 100, 3, 0, 83, 100, 4, 0, 83, 100, 0, 0, 83]
可以通過dis.opname[100]檢視,即為LOAD_CONST。而後的兩個位元組表示指令的引數。而dis輸出的位元組碼指令中,
第二列的位元組碼索引則是指當前指令在co_code序列中所在的位置。
dis輸出的位元組碼指令中,部分指令是沒有引數, 在co_code 中也同樣可以看到,83(RETURN_VALUE)直接接上下一條指令100(LOAD_CONST)。