如何解决为什么反汇编python类定义会显示两个具有相同类名的相同LOAD_CONST?
我想知道为什么在定义一个类时python两次用相同的值(类名)生成一个LOAD_CONST
。当我运行此代码时:
from dis import dis
dis("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_VALUE
Disassembly of <code object A at 0x0000021DCE681B70,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位上运行
解决方法
TL; DR:在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')
。 op名称后面的2表示被削减的位置参数的数量。最右边的位置参数在堆栈的顶部,因此它们将是:类名'A'
,然后是体现类定义的MAKE_FUNCTION中剩余的obj。这些自变量的“下方”是可调用的__build_class__
,此操作也使用该可调用的__build_class__(func,name,/,*bases,[metaclass],**kwds) -> class
。没有提供12 STORE_NAME 0 (A)
接受的可选参数。
A = <top of stack>
14 LOAD_CONST 2 (None)
,实际上是将新创建的类obj绑定到命名空间中
None
RETURN_VALUE将返回堆栈的顶部,但是类语句exec不需要返回值,因此在返回之前先加载16 RETURN_VALUE
。
__build_class__
我们完成了。
要了解为什么pip install stocker
import stocker
将函数作为第一个参数,请参阅this post from Guido。我想为实现方便起见,将一个函数对象用于类主体。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。