python中的dis剖析原始碼及引數含義的講解

2021-08-15 22:54:54 字數 2246 閱讀 1746

python **先被編譯為位元組碼後,再由python虛擬機器來執行位元組碼, python的位元組碼是一種類似彙編指令的中間語言, 乙個python語句會對應若干位元組碼指令,虛擬機器一條一條執行位元組碼指令, 從而完成程式執行。

python dis 模組支援對python**進行反彙編, 生成位元組碼指令。

先來一小段**:

[python]view plain

copy

in[6

]: def

test():  

...         x = 1

...         if

x < 

3:  

...             return

"yes"

...         else

:  ...             return

"no"

**執行

後會輸出:

[python]view plain

copy

in[7

]: import

dis  

in[8

]: dis.dis(test)  20

load_const               1(

1)  

3store_fast               

0(x)  36

load_fast                

0(x)  

9load_const               2(

3)  

12compare_op               

0(<)  

15pop_jump_if_false       224

18load_const               3(

'yes'

)  21

return_value          

6>>   

22load_const               4(

'no'

)  25

return_value          

26load_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函式的位元組碼指令序列。

將此序列列印出來,

[python]view plain

copy

code = [ord(i) 

fori 

inlist(test.__code__.co_code)]  

print

code  

輸出:[python]view plain

copy

[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輸出的位元組碼指令, 以[100,1,0]序列為例。100表示在python位元組碼定義中的索引,在python**中,

可以通過dis.opname[100]檢視,即為load_const。而後的兩個位元組表示指令的引數。而dis輸出的位元組碼指令中,

第二列的位元組碼索引則是指當前指令在co_code序列中所在的位置。

dis輸出的位元組碼指令中,部分指令是沒有引數, 在co_code 中也同樣可以看到,83(return_value)直接接上下一條指令100(load_const)。

ConcurrentHashMap的原始碼分析

put final v putval k key,v value,boolean onlyifabsent 在上一步的else if中 f 不為null時,則判斷f的hash值是否為moved,即 1,如果為 1,表示正在擴容 else if fh f.hash moved 協助資料遷移 tab h...

DispatcherServlet的原始碼和流程分析

1 自動配置dispatcherservlet和dispatcherservletregistry 2 註冊dispatcherservlet到servletcontext 3 初始化mvc的元件 handler執行完成後,向dispatcherservlet 返回乙個modelandview物件 ...

Mybatis中Logging模組的原始碼分析

週末又來到了公司吹吹空調,順便記錄下mybatis的點點滴滴。首先mybatis不定義日誌系統,完全依賴於第三方系統完成日誌記錄,利用介面卡模式完成實際操作,原始碼如下 1 定義乙個log介面,具有如下方法 public inte ce log2 然後引入第三方日誌,比如 loggingimpl,實...