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)]
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,實...