我想知道你是否在你的代码中使用@staticmethod decorator。
我个人不使用它,因为写@staticmethod然后自己需要更多的信件。
使用它的唯一好处(来自我)可能是更好的代码清晰度,但由于我经常为sphinx编写方法描述,我总是说明一个方法是否正在使用对象。
或许我应该开始使用@staticmethod decorator?
答案 0 :(得分:32)
是否使用@staticmethod
取决于您想要达到的目标。忽略装饰器,因为要输入更多内容是一个相当愚蠢的原因(没有冒犯!)并且表明你还没有理解Python中静态方法的概念!
静态方法独立于类和任何类实例。它们仅将类作用域用作命名空间。如果省略@staticmethod
装饰器,则创建一个在不构造实例的情况下无法使用的实例方法。
这是一个非常简单的课程Foo
:
>>> class Foo(object):
... @staticmethod
... def foo():
... print 'foo'
...
... def bar(self):
... print 'bar'
现在,Foo.foo()
是一个可以直接调用的静态方法:
>>> Foo.foo()
foo
另一方面, Foo.bar()
是实例方法,只能从Foo
的实例(对象)中调用:
>>> Foo.bar()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method foo() must be called with Foo instance as first argument (got nothing instead)
>>> foo = Foo()
>>> foo.bar()
bar
回答您的问题:如果您想定义静态方法,请使用@staticmethod
。否则,不要。
如果您的方法不使用self
,因此 可以作为静态方法编写,请问自己:您是否希望从外部访问此功能而不必使用一个实例?大多数时候,答案是:否。
答案 1 :(得分:1)
假设我们要在类abs
中定义Math
方法,那么我们有两个选择:
class Math():
def abs(n):
if n>0:
return n
else:
return -n
class Math2():
@staticmethod
def abs(n):
if n>0:
return n
else:
return -n
在Python2中:
>>> Math.abs(-2)
TypeError: unbound method abs() must be called with Math instance as
first argument (got int instance instead)
>>>Math().abs(-2)
TypeError: abs() takes exactly 1 argument (2 given)
>>> Math2.abs(-2)
2
>>> Math2().abs(-2)
2
python2自动将Math().abs(-2)
作为Math().abs(self,-2)
,因此您必须使用@staticmethod
。
在Python3中
>>>Math.abs(-3)
3
>>>Math().abs(-3)
TypeError: abs() takes 1 positional argument but 2 were given
>>>Math2.abs(-3)
3
>>>Math2().abs(-3)
3
在python3中,您可以在没有静态方法的情况下使用classname.method()
,但是当有人试图使用instance.method()
时会引发TypeError。
答案 2 :(得分:0)
@staticmethod
装饰器可以节省您的输入并提高可读性。
class Example:
@staticmethod
def some_method():
return
与:
相同class Example:
def some_method():
return
some_method = staticmethod(some_method)
我认为你可能会对Python中的静态方法感到困惑,因为术语与其他语言不同。常规方法“绑定”到实例(self
),类方法“绑定”到类(cls
),而静态方法根本不“绑定”(并且不能访问实例或类属性。
请参阅:
答案 3 :(得分:0)
除了前面的答案, 来自pythons doc @staticmethod:
可以在类(例如C.f())或实例(例如C()。f())上调用它。该实例除其类外均被忽略。
class Test:
@staticmethod
def Foo():
print('static Foo')
def Bar():
print('static Bar')
Test.foo() # static Foo
Test.bar() # static Bar
obj = Test()
obj.foo() # static Foo ; note that you can call it from class instance
obj.bar() # ERROR