在Python字节码中,如果函数returns什么都没有,为什么在CALL_FUNCTION指令之后会有POP_TOP指令?
In Python bytecode, why is there a POP_TOP instruction after the CALL_FUNCTION instruction if the function returns nothing?
我正在研究Python字节码,发现在CALL_FUNCTION
指令之后有一个POP_TOP
指令。 POP_TOP
在这里做什么?
a = 1
b = 2
c = a + b
print(c)
def func(e, f, g):
h = e + f + g
func(a, b, c)
经过运行python3 -m dis main.py
,我得到了
1 0 LOAD_CONST 0 (1)
2 STORE_NAME 0 (a)
2 4 LOAD_CONST 1 (2)
6 STORE_NAME 1 (b)
3 8 LOAD_NAME 0 (a)
10 LOAD_NAME 1 (b)
12 BINARY_ADD
14 STORE_NAME 2 (c)
4 16 LOAD_NAME 3 (print)
18 LOAD_NAME 2 (c)
20 CALL_FUNCTION 1
22 POP_TOP
5 24 LOAD_CONST 2 (<code object func at 0x7fb9aebb59c0, file "btins3.py", line 5>)
26 LOAD_CONST 3 ('func')
28 MAKE_FUNCTION 0
30 STORE_NAME 4 (func)
8 32 LOAD_NAME 4 (func)
34 LOAD_NAME 0 (a)
36 LOAD_NAME 1 (b)
38 LOAD_NAME 2 (c)
40 CALL_FUNCTION 3
42 POP_TOP
44 LOAD_CONST 4 (None)
46 RETURN_VALUE
请参阅第 22 行和第 42 行。
Python 中不存在“return什么都没有”的函数。即使一个函数没有明确地 return
一个值,函数 隐含地 returns None
(如果你 dis.dis(func)
你'会在生成的字节码中看到它)。
如果不这样做,字节码编译器将需要更复杂,因为它需要一些方法来区分有和没有 return 值的函数(并且因为函数首先是 class 对象并且可以重新分配,你甚至不能用编译时规则做到这一点;它必须在运行时逐个调用地处理);实际上,它可以无条件地将它们视为具有 return 值,只是某些 return 值(隐式 None
)不如其他值有用。
我正在研究Python字节码,发现在CALL_FUNCTION
指令之后有一个POP_TOP
指令。 POP_TOP
在这里做什么?
a = 1
b = 2
c = a + b
print(c)
def func(e, f, g):
h = e + f + g
func(a, b, c)
经过运行python3 -m dis main.py
,我得到了
1 0 LOAD_CONST 0 (1)
2 STORE_NAME 0 (a)
2 4 LOAD_CONST 1 (2)
6 STORE_NAME 1 (b)
3 8 LOAD_NAME 0 (a)
10 LOAD_NAME 1 (b)
12 BINARY_ADD
14 STORE_NAME 2 (c)
4 16 LOAD_NAME 3 (print)
18 LOAD_NAME 2 (c)
20 CALL_FUNCTION 1
22 POP_TOP
5 24 LOAD_CONST 2 (<code object func at 0x7fb9aebb59c0, file "btins3.py", line 5>)
26 LOAD_CONST 3 ('func')
28 MAKE_FUNCTION 0
30 STORE_NAME 4 (func)
8 32 LOAD_NAME 4 (func)
34 LOAD_NAME 0 (a)
36 LOAD_NAME 1 (b)
38 LOAD_NAME 2 (c)
40 CALL_FUNCTION 3
42 POP_TOP
44 LOAD_CONST 4 (None)
46 RETURN_VALUE
请参阅第 22 行和第 42 行。
Python 中不存在“return什么都没有”的函数。即使一个函数没有明确地 return
一个值,函数 隐含地 returns None
(如果你 dis.dis(func)
你'会在生成的字节码中看到它)。
如果不这样做,字节码编译器将需要更复杂,因为它需要一些方法来区分有和没有 return 值的函数(并且因为函数首先是 class 对象并且可以重新分配,你甚至不能用编译时规则做到这一点;它必须在运行时逐个调用地处理);实际上,它可以无条件地将它们视为具有 return 值,只是某些 return 值(隐式 None
)不如其他值有用。