我想知道为什么PythonLOAD_CONST在定义一个类时会两次使用相同的值(类名)。当我运行这段代码时:from dis import disdis("class A(): pass")这是我得到的输出: 1 0 LOAD_BUILD_CLASS 2 LOAD_CONST 0 (<code object A at 0x0000021DCE681B70, file "<dis>", line 1>) 4 LOAD_CONST 1 ('A') 6 MAKE_FUNCTION 0 8 LOAD_CONST 1 ('A') 10 CALL_FUNCTION 2 12 STORE_NAME 0 (A) 14 LOAD_CONST 2 (None) 16 RETURN_VALUEDisassembly of <code object A at 0x0000021DCE681B70, file "<dis>", line 1>: 1 0 LOAD_NAME 0 (__name__) 2 STORE_NAME 1 (__module__) 4 LOAD_CONST 0 ('A') 6 STORE_NAME 2 (__qualname__) 8 LOAD_CONST 1 (None) 10 RETURN_VALUE正如您在第 3 行和第 5 行中看到的,有两个LOAD_CONST带有类名。LOAD_CONST如果类名已经加载,为什么还要使用相同的数据创建第二个呢?MAKE_FUNCTION这和他们之间有什么关系吗LOAD_CONST?我在 python 3.7.4 64 位上运行它
1 回答
慕姐4208626
TA贡献1852条经验 获得超7个赞
CPython 中的类型创建暂时使用函数对象作为类主体。第一个“A”用于该函数的名称。第二个“A”用于类名。
帖子的其余部分详细解释了这个反汇编:
0 LOAD_BUILD_CLASS
压builtins.__build_class__
入堆栈。随后由 CALL_FUNCTION 调用它来构造一个类。
2 LOAD_CONST 0 (<code object A at 0xCAFEF00D, file "<dis>", line 1>)
将代码 obj 压入堆栈(这实际上包含解析的类块 - 继续阅读)
4 LOAD_CONST 1 ('A')
将“A”压入堆栈
6 MAKE_FUNCTION 0
将新的函数对象压入堆栈。此操作还消耗堆栈上的前两个内容(此函数的代码 obj 及其限定名称)
8 LOAD_CONST 1 ('A')
再次将“A”压入堆栈,以便可以用作 中的第二个参数builtins.__build_class__
,即类名。
10 CALL_FUNCTION 2
使用堆栈中的“A”和一个函数对象,调用__build_class__(<func>, 'A')
. 操作名称后面的 2 指的是所咀嚼的位置参数的数量。最右边的位置参数位于堆栈顶部,因此它们将是:类名'A'
,然后是 MAKE_FUNCTION 中剩余的 obj,它体现了类定义。这些参数的“下面”是可调用的__build_class__
,这个操作也消耗它。未提供任何接受的可选参数__build_class__(func, name, /, *bases, [metaclass], **kwds) -> class
。
12 STORE_NAME 0 (A)
A = <top of stack>
,本质上是在命名空间中绑定新创建的类 obj
14 LOAD_CONST 2 (None)
RETURN_VALUE 将返回堆栈顶部,但类语句 exec 不需要返回值,因此None
在返回之前加载。
16 RETURN_VALUE
我们完成了。
添加回答
举报
0/150
提交
取消