2013-04-23 134 views
15

我知道他們做了什麼,我見過很多這兩個例子,但我還沒有找到一個例子,我不得不使用classmethod而不是用staticmethod代替它。爲什麼使用classmethod而不是staticmethod?

我見過的classmethod最常見的例子是用於創建新實例的類本身的,像這樣的(很簡單的例子,有沒有使用ATM的方法,但你的想法。):

class Foo: 
    @classmethod 
    def create_new(cls): 
     return cls() 

當調用foo = Foo.create_new()時,將返回一個新的Foo實例。 現在爲什麼不能我只是用這個代替:

class Foo: 
    @staticmethod 
    def create_new(): 
     return Foo() 

它不完全一樣的,爲什麼要我曾經使用classmethodstaticmethod

+7

@KevinBrydon對那個頁面上的OP問題沒有*答案*,但它可能在那裏的註釋中。我不知道是否有足夠的理由來解決這個問題 – jamylak 2013-04-23 14:41:59

+1

這個問題不是鏈接問題的重複。鏈接問題的答案沒有說明爲什麼要使用靜態方法的類方法,反之亦然。 – spacetyper 2017-03-14 16:34:38

回答

17

有你的榜樣差別不大,但假設您創建的Foo一個子類,並呼籲子類中的方法create_new ...

class Bar(Foo): 
    pass 

obj = Bar.create_new() 

...那麼這個基類會引起新的Bar對象要創建...

class Foo: 
    @classmethod 
    def create_new(cls): 
     return cls() 

...而這個基類會導致創建一個新的Foo對象...

class Foo: 
    @staticmethod 
    def create_new(): 
     return Foo() 

...所以選擇取決於你想要的行爲。

+0

根本沒有想到亞類,我的壞!感謝您的快速回答:)我會盡快接受。 – 2013-04-23 14:43:36

5

是的,這兩個班級也會這樣做。

不過,現在想象類的子類型:

class Bar (Foo): 
    pass 

現在呼籲Bar.create_new做不同的東西。對於靜態方法,您會得到一個Foo。對於類方法,您會得到一個Bar

所以重要的區別是類方法獲取作爲參數傳遞的類型。

4

docs,類方法接收它的類作爲隱式參數,而靜態方法不知道它們所在的類。

這對於您想要用子類中的不同行爲覆蓋的繼承靜態方法的情況很有用。