当我尝试使用内置的使用静态方法从类的体内,并定义静态方法staticmethod
的功能作为装饰,就像这样:
class Klass(object):
@staticmethod # use as decorator
def _stat_func():
return 42
_ANS = _stat_func() # call the staticmethod
def method(self):
ret = Klass._stat_func() + Klass._ANS
return ret
我得到以下错误:
Traceback (most recent call last):<br>
File "call_staticmethod.py", line 1, in <module>
class Klass(object):
File "call_staticmethod.py", line 7, in Klass
_ANS = _stat_func()
TypeError: 'staticmethod' object is not callable
我明白为什么会发生(描述符的结合),并且可以通过手动转换解决它_stat_func()
到一个静态方法在最后一次使用后,就像这样:
class Klass(object):
def _stat_func():
return 42
_ANS = _stat_func() # use the non-staticmethod version
_stat_func = staticmethod(_stat_func) # convert function to a static method
def method(self):
ret = Klass._stat_func() + Klass._ANS
return ret
所以我的问题是:
有没有更好的,如清洁剂或更多的“Python化”的方式来做到这一点?
staticmethod
的对象显然有__func__
属性保管原生功能(是有道理的,他们不得不)。 因此,这将工作:
class Klass(object):
@staticmethod # use as decorator
def stat_func():
return 42
_ANS = stat_func.__func__() # call the staticmethod
def method(self):
ret = Klass.stat_func()
return ret
顺便说一句,虽然我怀疑是一个静态方法对象有某种属性保管原有功能的,我没有具体的想法。 在教人以渔,而不是给他们一条鱼的精神,这是我做的调查,发现了(一个C&P从我的Python会话):
>>> class Foo(object):
... @staticmethod
... def foo():
... return 3
... global z
... z = foo
>>> z
<staticmethod object at 0x0000000002E40558>
>>> Foo.foo
<function foo at 0x0000000002E3CBA8>
>>> dir(z)
['__class__', '__delattr__', '__doc__', '__format__', '__func__', '__get__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
>>> z.__func__
<function foo at 0x0000000002E3CBA8>
类似种种在交互式会话挖掘( dir
是非常有帮助的)往往可以解决这些问题的种类非常快。
这是我喜欢的方式:
class Klass(object):
@staticmethod
def stat_func():
return 42
_ANS = stat_func.__func__()
def method(self):
return self.__class__.stat_func() + self.__class__._ANS
我喜欢这个解决方案Klass.stat_func
因为, DRY原则 。 让我想起了为什么有一个新的理由super()
在Python 3 :)
但我同意其他人,通常是最好的选择是定义一个模块级的功能。
例如与@staticmethod
功能,递归可能不是很好看(你可能需要通过调用打破DRY原则Klass.stat_func
内Klass.stat_func
)。 那是因为你没有提到self
的静态方法里面。 随着模块级的功能,一切看起来OK。
这是由于静态方法是一个描述符,需要一个类级属性取行使描述协议,并得到真正的调用。
从源代码:
它可以被称为无论是在类别(例如Cf()
或上的一个实例(例如, C().f()
); 除了它的类实例被忽略。
但是,从里面的类不能直接当它被定义。
但是如前所述一个评论,这是不是真的在所有一个“Python化”设计。 只需使用一个模块级函数。
怎么样的类定义后注射类的属性?
class Klass(object):
@staticmethod # use as decorator
def stat_func():
return 42
def method(self):
ret = Klass.stat_func()
return ret
Klass._ANS = Klass.stat_func() # inject the class attribute with static method value
这个怎么样的解决方案? 它不依赖于知识@staticmethod
装饰的实现。 内部类STATICMETHOD扮演的静态初始化函数的容器。
class Klass(object):
class StaticMethod:
@staticmethod # use as decorator
def _stat_func():
return 42
_ANS = StaticMethod._stat_func() # call the staticmethod
def method(self):
ret = self.StaticMethod._stat_func() + Klass._ANS
return ret
根据下面的博客,调用类中的一个静态方法时,调用函数必须是一个类的方法,因此增加@classmethod
你的方法定义可以解决这个问题。
关于如何使用静态,类或抽象方法在Python的权威指南