python编译过程和解释过程的不同_Python编译/解释过程
字節(jié)碼實(shí)際上不會(huì)被解釋為機(jī)器碼,除非您正在使用一些特殊的實(shí)現(xiàn),比如pypy。
除此之外,你的描述是正確的。字節(jié)碼被加載到Python運(yùn)行時(shí)中,并由一個(gè)虛擬機(jī)進(jìn)行解釋,虛擬機(jī)是一段代碼,它讀取字節(jié)碼中的每個(gè)指令并執(zhí)行指示的任何操作。您可以通過(guò)dis模塊看到這個(gè)字節(jié)碼,如下所示:>>> def fib(n): return n if n < 2 else fib(n - 2) + fib(n - 1)
...
>>> fib(10)
55
>>> import dis
>>> dis.dis(fib)
1 0 LOAD_FAST 0 (n)
3 LOAD_CONST 1 (2)
6 COMPARE_OP 0 (
9 JUMP_IF_FALSE 5 (to 17)
12 POP_TOP
13 LOAD_FAST 0 (n)
16 RETURN_VALUE
>> 17 POP_TOP
18 LOAD_GLOBAL 0 (fib)
21 LOAD_FAST 0 (n)
24 LOAD_CONST 1 (2)
27 BINARY_SUBTRACT
28 CALL_FUNCTION 1
31 LOAD_GLOBAL 0 (fib)
34 LOAD_FAST 0 (n)
37 LOAD_CONST 2 (1)
40 BINARY_SUBTRACT
41 CALL_FUNCTION 1
44 BINARY_ADD
45 RETURN_VALUE
>>>
詳細(xì)說(shuō)明
很重要的一點(diǎn)是要明白,上面的代碼從來(lái)不是由CPU執(zhí)行的;它也從來(lái)沒(méi)有被轉(zhuǎn)換成某種東西(至少,不是在Python的官方C實(shí)現(xiàn)上)。CPU執(zhí)行虛擬機(jī)代碼,虛擬機(jī)代碼執(zhí)行字節(jié)碼指令指示的工作。當(dāng)解釋器想要執(zhí)行fib函數(shù)時(shí),它一次讀取一條指令,并按照它們的指示執(zhí)行。它查看第一條指令LOAD_FAST 0,從而從保存參數(shù)的位置獲取參數(shù)0(傳遞給n的fib),并將其推送到解釋器堆棧(Python的解釋器是一個(gè)堆棧機(jī))。在讀取下一條指令LOAD_CONST 1時(shí),它從函數(shù)擁有的常量集合(在本例中恰好是2)中獲取常量1,并將其推送到堆棧上。你可以看到這些常數(shù):>>> fib.func_code.co_consts
(None, 2, 1)
下一條指令COMPARE_OP 0告訴解釋器彈出最上面的兩個(gè)堆棧元素并在它們之間執(zhí)行不等式比較,將布爾結(jié)果推回到堆棧上。第四條指令根據(jù)布爾值決定是向前跳五條指令還是繼續(xù)下一條指令。所有這些措辭都解釋了fib中條件表達(dá)式的if n < 2部分。對(duì)于您來(lái)說(shuō),梳理出字節(jié)碼其余部分的含義和行為將是一個(gè)非常有指導(dǎo)意義的練習(xí)。唯一一個(gè),我不確定是POP_TOP;我猜JUMP_IF_FALSE的定義是將其布爾參數(shù)留在堆棧上,而不是彈出它,所以必須顯式彈出它。
更具指導(dǎo)意義的是檢查原始字節(jié)碼的fib,因此:>>> code = fib.func_code.co_code
>>> code
'|\x00\x00d\x01\x00j\x00\x00o\x05\x00\x01|\x00\x00S\x01t\x00\x00|\x00\x00d\x01\x00\x18\x83\x01\x00t\x00\x00|\x00\x00d\x02\x00\x18\x83\x01\x00\x17S'
>>> import opcode
>>> op = code[0]
>>> op
'|'
>>> op = ord(op)
>>> op
124
>>> opcode.opname[op]
'LOAD_FAST'
>>>
因此,您可以看到字節(jié)碼的第一個(gè)字節(jié)是LOAD_FAST指令。下一對(duì)字節(jié)'\x00\x00'(16位中的數(shù)字0)是LOAD_FAST的參數(shù),并告訴字節(jié)碼解釋器將參數(shù)0加載到堆棧中。
總結(jié)
以上是生活随笔為你收集整理的python编译过程和解释过程的不同_Python编译/解释过程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: linux安装mysql社区版 rpm_
- 下一篇: redis占用内存过低_使用多种数据结构