Joe*_*Joe 3 python binding cpython dynamic-binding
在询问有关反思的问题时,我问:
很好的答案.但说
myobject.foo()和之间有区别x = getattr(myobject, "foo"); x();.即使它只是化妆品.在第一个中,foo()是静态编译的.在第二种情况下,字符串可以通过多种方式生成. - 乔1小时前
得到了答案:
呃,马铃薯/马铃薯...在python中,niether是静态编译的,所以它们或多或少相当. - SWeko 1小时前
我知道Python对象的成员存储在字典中,并且一切都是动态的,但我假设给出了以下代码:
class Thing():
def m(self):
pass
t = Thing()
Run Code Online (Sandbox Code Playgroud)
生成.pyc时,以下代码会以某种方式静态编译:
t.m()
Run Code Online (Sandbox Code Playgroud)
即编译器知道地址m(),因此在运行时没有点绑定.那个或运行时会缓存后续查找.
虽然这总是涉及到字典:
meth = getattr(t, "m")
meth()
Run Code Online (Sandbox Code Playgroud)
是否所有调用都被视为字典中的字符串查找?或者这两个例子实际上是相同的吗?
它们并不完全相同,但它们都是字典查找,可以用反汇编程序显示dis.dis.
特别是,请注意该LOAD_ATTR指令通过名称动态查找属性.根据文档,它"替换TOS [堆栈顶部] getattr(TOS, co_names[namei])".
>>> from dis import dis
>>> dis(lambda: t.m())
1 0 LOAD_GLOBAL 0 (t)
3 LOAD_ATTR 1 (m)
6 CALL_FUNCTION 0
9 RETURN_VALUE
>>> dis(lambda: getattr(t, 'm')())
1 0 LOAD_GLOBAL 0 (getattr)
3 LOAD_GLOBAL 1 (t)
6 LOAD_CONST 0 ('m')
9 CALL_FUNCTION 2
12 CALL_FUNCTION 0
15 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)