静态方法语法混乱
Static method syntax confusion
这就是我们在 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 不会给你语法错误,因为方法的绑定(负责传入 self
)是一个 runtime行动。
只有当您在 class 或实例上查找方法时,才会绑定方法(因为函数是 descriptors they produce a method when looked up this way). This is done via the descriptor.__get__()
method, which is called by the object.__getattribute__()
method,当您尝试访问 Python fun
A
class 或 A()
实例上的属性。
您始终可以 'unwrap' 绑定方法并获取下面的未包装函数以直接调用它:
A.fun.__func__()
顺便说一句,这正是 staticmethod
所做的; 'intercept' 描述符绑定和 return 原始函数对象而不是绑定方法。换句话说,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!
这就是我们在 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 不会给你语法错误,因为方法的绑定(负责传入 self
)是一个 runtime行动。
只有当您在 class 或实例上查找方法时,才会绑定方法(因为函数是 descriptors they produce a method when looked up this way). This is done via the descriptor.__get__()
method, which is called by the object.__getattribute__()
method,当您尝试访问 Python fun
A
class 或 A()
实例上的属性。
您始终可以 'unwrap' 绑定方法并获取下面的未包装函数以直接调用它:
A.fun.__func__()
顺便说一句,这正是 staticmethod
所做的; 'intercept' 描述符绑定和 return 原始函数对象而不是绑定方法。换句话说,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!