2011-07-27 68 views
10

我在想你是否在代码中使用@staticmethod装饰器。使用@staticmethod有什么好处吗?

我个人并不使用它,因为它需要更多字母才能写出@staticmethod,然后是自己。

使用它的唯一好处可能是更好的代码清晰度,但由于我通常为sphinx编写方法描述,因此我总是说明方法是否使用对象。

或者我应该开始使用@staticmethod装饰器?

+0

其实,我仍然感到困惑:是否有一些地方需要在python3中使用staticmethod?我发现很多地方并不需要使用静态方法。 –

回答

28

是否使用@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,因此可能被写为静态方法,问问自己:你是否曾经想从外面访问这个函数而没有实例?大多数情况下,答案是:No.

+5

+1:“忽略装饰者,因为有更多的类型是一个相当愚蠢的原因”。放下道歉。这很愚蠢。 –

+2

只需添加一个使用静态方法而不是自己的其他原因 - 它不仅适用于python,也适用于未来的维护者。它强调“这个函数不依赖于类或实例的状态”,而不是类方法或未修饰的方法。对于不熟悉代码的维护者(例如:你,从现在开始5年),这使得学习代码库的速度更快。 –

+2

谢谢你的回答,现在当我看到这真的是一个愚蠢的原因:)我还有很多东西要学,但是多亏了你们,学习并不像以前那么痛苦。 – Michal

0

@staticmethod装饰器可以节省您的打字时间并提高可读性。

class Example: 
    @staticmethod 
    def some_method(): 
     return 

是一样的:

class Example: 
    def some_method(): 
     return 
    some_method = staticmethod(some_method) 

我想你可能会感到困惑什么是静态方法是Python作为术语从其他语言不同。常规方法与实例“绑定”(self),类方法与类“绑定”(cls),而静态方法根本没有“绑定”(并且无法访问实例和类属性。

参见:

0

假设我们要定义Mathabs方法,那么我们有两种选择:

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异常。

+0

python2和python3之间的这个不同让我很困惑。 –