2011-07-27 112 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之間的這個不同讓我很困惑。 –