静态方法语法混淆

时间:2015-09-15 19:08:26

标签: 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首先不会给我一个语法错误?

1 个答案:

答案 0 :(得分:8)

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

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

你可以随时解开'下面的未包装函数的绑定方法和范围直接调用它:

A.fun.__func__()

顺便说一下,这正是staticmethod的作用;它是拦截'描述符绑定并返回原始函数对象而不是绑定方法。换句话说,staticmethod 撤消正常的运行时方法绑定:

演示:

>>> 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!