python函数/方法调用是否存在任何静态特性?
我问: 回答得好。但是说python函数/方法调用是否存在任何静态特性?,python,binding,cpython,dynamic-binding,Python,Binding,Cpython,Dynamic Binding,我问: 回答得好。但是说myobject.foo()和x=getattr(myobject,“foo”)之间有区别;x()。即使只是表面上的。在第一个示例中,foo()以静态方式编译。在第二种情况下,字符串可以通过多种方式生成乔1小时前 答案是: 嗯,马铃薯/马铃薯茄。。。在python中,niether是静态编译的,因此它们或多或少是等效的斯维科1小时前 我知道Python对象的成员存储在字典中,并且所有内容都是动态的,但我假设给定以下代码: class Thing(): def m(se
myobject.foo()
和x=getattr(myobject,“foo”)之间有区别;x()代码>。即使只是表面上的。在第一个示例中,foo()以静态方式编译。在第二种情况下,字符串可以通过多种方式生成乔1小时前
答案是:
嗯,马铃薯/马铃薯茄。。。在python中,niether是静态编译的,因此它们或多或少是等效的斯维科1小时前
我知道Python对象的成员存储在字典中,并且所有内容都是动态的,但我假设给定以下代码:
class Thing():
def m(self):
pass
t = Thing()
生成.pyc时,以下代码将以某种方式进行静态编译:
t.m()
i、 e.编译器知道m()
的地址,因此在运行时没有点绑定。或者运行时将缓存后续查找
然而,这总是涉及到查字典:
meth = getattr(t, "m")
meth()
是否所有调用都被视为字典中的字符串查找?或者这两个示例实际上是相同的?所有调用都被视为字典查找(好吧,python内部可能会进行某种优化,但就其工作方式而言,您可以假设它们是字典查找)
python中没有静态编译。甚至可以这样做:
t = Thing()
t.m = lambda : 1
t.m()
它们并不完全相同,但它们都是字典查找,正如反汇编程序所示
特别要注意的是,LOAD\u ATTR
指令通过名称动态查找属性。根据文档,它“用getattr(TOS,co_names[namei])
取代了TOS[top of stack]
不仅类在运行时是可修改的(如在上);但即使是类
关键字也会在运行时“执行”:
类定义是一个可执行文件
陈述它首先评估
继承列表(如果存在)。每个
继承列表中的项应为
对类对象或类求值
允许子类化的类型。这个
类的套件然后在
新的执行框架(参见第节
命名和绑定),使用新的
已创建本地命名空间和
原始全局命名空间。(通常,
该套件仅包含功能
定义。)当类的套件
完成执行,它的执行
框架被丢弃,但其局部
名称空间已保存。[4] 类对象
然后使用继承创建
基类和
已保存的本地命名空间
属性字典。类名
在中绑定到此类对象
原始本地名称空间
()
换句话说,在启动时,解释器执行类
块中的代码,并保留结果上下文。在编译时,无法知道类的外观。这取决于您是询问Python语言,还是询问特定的实现,如CPython
语言本身并没有说两者是相同的,所以直接属性访问可能会以某种方式得到优化。然而,Python的动态特性使得它很难做到一致,因此在CPython中,两者实际上是相同的
话虽如此,直接t.m()
的速度可能是使用getattr()
的两倍,因为它涉及一个字典查找,而不是使用getattr()
:即全局名称getattr()
本身必须在字典中查找。使用getattr
您可以访问名称不是有效标识符的属性,尽管我不确定是否存在使用类似属性而不是使用字典的用例
>>> setattr(t, '3', lambda : 4)
>>> t.3()
File "<stdin>", line 1
t.3()
^
SyntaxError: invalid syntax
>>> getattr(t, '3')()
4
设置属性(t,'3',λ:4)
>>>t.3()
文件“”,第1行
t、 3()
^
SyntaxError:无效语法
>>>getattr(t,'3')()
4.
>>> setattr(t, '3', lambda : 4)
>>> t.3()
File "<stdin>", line 1
t.3()
^
SyntaxError: invalid syntax
>>> getattr(t, '3')()
4