Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python函数/方法调用是否存在任何静态特性?_Python_Binding_Cpython_Dynamic Binding - Fatal编程技术网

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