为什么2个不同的python lambda具有相同的字节码?

问题描述:

我看到一些我不明白的行为。我认为python函数的字节码是执行结果的字节码,但在这里我有2个不同的lambda函数,它们具有相同的字节码,但显然做了不同的事情。怎么会这样?由于consts不同为什么2个不同的python lambda具有相同的字节码?

a = b'|\x00\x00d\x01\x00\x17S' 
b = b'|\x00\x00d\x01\x00\x17S' 
5 4 

字节码不在代码对象的唯一事情

a = lambda x: x+4 
b = lambda y: y+3 
print('a = ', a.__code__.co_code) 
print('b = ', b.__code__.co_code) 
print(a(1), b(1)) 

生成此输出。如果您在使用dis.dis dissassemble的功能,你可以看到发生了什么:

>>> import dis 
>>> a = lambda x: x + 4 
>>> b = lambda y: y + 3 
>>> dis.dis(a) 
    1   0 LOAD_FAST    0 (x) 
       3 LOAD_CONST    1 (4) 
       6 BINARY_ADD 
       7 RETURN_VALUE 
>>> dis.dis(b) 
    1   0 LOAD_FAST    0 (y) 
       3 LOAD_CONST    1 (3) 
       6 BINARY_ADD 
       7 RETURN_VALUE 

正在发生的事情是,有也与代码对象连结的本常量的元组。字节代码只是说在这个元组的索引中加载常量。它们都具有相同的字节码,但从元组中加载不同的值。你可以用co_consts属性看到:

>>> a.__code__.co_consts 
(None, 4) 
>>> b.__code__.co_consts 
(None, 3) 

您可以更改这也使得不同的功能:

>>> import types 
>>> c_code = types.CodeType(
    a.__code__.co_argcount, a.__code__.co_kwonlyargcount, a.__code__.co_nlocals, 
    a.__code__.co_stacksize, a.__code__.co_flags, a.__code__.co_code, (None, 5), 
    a.__code__.co_names, a.__code__.co_varnames, a.__code__.co_filename, 
    a.__code__.co_name, a.__code__.co_firstlineno, a.__code__.co_lnotab, 
    a.__code__.co_freevars, a.__code__.co_cellvars 
) 
>>> c = types.FunctionType(c_code, globals()) 
>>> a(0) 
4 
>>> c(0) 
5 

>>> print('a = ', a.__code__.co_consts) 
a = (None, 4) 
>>> print('a = ', b.__code__.co_consts) 
a = (None, 3)