python - 静态方法语法困惑

标签 python python-2.7 methods static-methods

这就是我们在 Python 中创建静态函数的方式:

class A:
   @staticmethod
   def fun():
      print 'hello'

A.fun()

这按预期工作并打印 hello

如果是成员函数而不是静态函数,我们使用self:

class A:
   def fun(self):
      print 'hello'

A().fun()

它也按预期工作并打印 hello

我对以下情况感到困惑:

class A:
   def fun():
      print 'hello'

在上面的例子中,没有staticmethod,也没有self。 Python 解释器可以接受这个定义。但是,我们不能将其称为上述任何一种方法,即:

A.fun()
A().fun()

两者都给出错误。

我的问题是:有什么方法可以调用这个函数吗?如果不是,为什么 Python 一开始不给我语法错误?

最佳答案

Python 不会给您语法错误,因为方法的绑定(bind)(负责传入 self)是一个运行时操作。

只有当您在类或实例上查找方法时,方法才会被绑定(bind)(因为函数是 descriptors 以这种方式查找时它们会生成一个方法)。这是通过 descriptor.__get__() method 完成的,由 object.__getattribute__() method 调用,当您尝试访问 A 类或 A() 实例上的 fun 属性时,Python 会调用它。

您始终可以“解包”绑定(bind)方法并获取下面的解包函数以直接调用它:

A.fun.__func__()

顺便说一句,这正是 staticmethod 所做的;它在那里“拦截”描述符绑定(bind)并返回原始函数对象而不是绑定(bind)方法。换句话说,staticmethod 撤销正常的运行时方法绑定(bind):

演示:

>>> class A(object): pass
... 
>>> def fun(): print 'hello!'
... 
>>> fun.__get__(None, A)  # binding to a class
<unbound method A.fun>
>>> fun.__get__(None, A)()   # calling a bound function, fails as there is no first argument
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method fun() must be called with A instance as first argument (got nothing instead)
>>> fun.__get__(None, A).__func__  # access the wrapped function
<function fun at 0x100ba8378>
>>> staticmethod(fun).__get__(None, A)  # staticmethod object just returns the function
<function fun at 0x100ba8378>
>>> staticmethod(fun).__get__(None, A)()  # so calling it works
hello!

关于python - 静态方法语法困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32593763/

相关文章:

python - 字符串和列表的连接

python - 将输出抓取并写入文本文件

c++ - 这有多虚拟?

python opencv 不会使用 Video-writer 对象编写视频?

Python: os.environ.get ('SSH_ORIGINAL_COMMAND' ) 返回 None

python - 这是获得随机舍入解决方案的正确方法吗?

python - 我如何知道亚马逊是否成功发送电子邮件

python-2.7 - Tkinter TreeView 选择

java - 阐述 : Method overloading is a static/compile-time binding but not polymorphism. 将静态绑定(bind)与多态性相关联是否正确?

java - boolean 数组无法正常工作