2013-04-23 14 views
15

So cosa fanno e ho visto molti esempi di entrambi, ma non ho trovato un singolo esempio in cui avrei dovuto usare classmethod invece di sostituirlo con uno staticmethod.Perché usare classmethod invece di staticmethod?

L'esempio più comune di classmethod che ho visto è per la creazione di una nuova istanza della classe stessa, come questo (esempio molto semplificato, non c'è l'uso del metodo di atm, ma si ottiene l'idea.):

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

Ciò restituire una nuova istanza di Foo quando si chiama foo = Foo.create_new(). Ora, perché non posso semplicemente utilizzare questo invece:

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

lo fa esattamente lo stesso, perché dovrei mai usare un classmethod nel corso di un staticmethod?

+7

@KevinBrydon non c'è * risposta * alla domanda OPs in quella pagina ma potrebbe essere nei commenti lì. Non so se questo è un motivo sufficiente per chiudere questo sebbene – jamylak

+1

Questa domanda NON è un duplicato della domanda collegata. Le risposte alla domanda collegata non si rivolgono a WHY perché useresti i metodi di classe su metodi statici, o viceversa. – spacetyper

risposta

17

C'è poca differenza nel tuo esempio, ma supponiamo si è creato una sottoclasse di Foo e chiamato il metodo create_new sulla sottoclasse ...

class Bar(Foo): 
    pass 

obj = Bar.create_new() 

... allora questa classe di base causerebbe un nuovo oggetto Bar da creare ...

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

... che tale classe di base causerebbe un nuovo oggetto Foo da creare ...

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

... quindi la scelta dipenderà dal comportamento desiderato.

+0

Non pensavo affatto alle sottoclassi, mio ​​male! Grazie per la rapida risposta :) Accetterò al più presto. –

5

Sì, quelle due classi avrebbero fatto lo stesso.

Tuttavia, ora immaginate un sottotipo di quella classe:

class Bar (Foo): 
    pass 

Ora chiamando Bar.create_new fa qualcosa di diverso. Per il metodo statico, ottieni Foo. Per il metodo di classe, ottieni Bar.

Quindi la differenza importante è che un metodo di classe ottiene il tipo passato come parametro.

4

Dal docs, un metodo di classe riceve la sua classe come argomento implicito, mentre i metodi statici non conoscono la classe in cui risiedono.

Questo può essere utile in situazioni in cui si ha un metodo statico ereditato che si desidera sovrascrivere con un comportamento diverso nella sottoclasse.

Problemi correlati