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

标签 python lambda cpython

我看到一些我不理解的行为。我认为 python 函数的字节码是被执行以产生结果的,但这里我有 2 个不同的 lambda 函数,它们具有完全相同的字节码,但显然做不同的事情。怎么会这样?

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))

产生这个输出:

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

最佳答案

字节码并不是代码对象中唯一的东西。如果使用 dis.dis 反汇编函数你可以看到发生了什么:

>>> 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

关于python - 为什么 2 个不同的 python lambda 具有相同的字节码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44574732/

相关文章:

python - 在Python中执行mysql查询时如何删除变量周围的单引号?

python - 将 3D numpy 矩阵 reshape 为 2D numpy 矩阵,保持行位置

c++ - const 方法中的非常量 lambda 捕获

syntax - 方案 | λ 与 λ?

python - unicodedata.digit 和 unicodedata.numeric 有什么区别?

python - 与 CPython 相比,PyPy 占用大量内存

python - 如何在openerp 7模块中创建动态字段?

python - 如何让我的 python 应用程序在继续之前等待某个子进程

c# - 为什么第二个 writeline 在使用 lambda 时打印出 12?

python - python对象什么时候创建的?