Metodi statici: come chiamare un metodo da un altro metodo?


95

Quando ho metodi regolari per chiamare un altro metodo in una classe, devo farlo

class test:
    def __init__(self):
        pass
    def dosomething(self):
        print "do something"
        self.dosomethingelse()
    def dosomethingelse(self):
        print "do something else"

ma quando ho metodi statici non riesco a scrivere

self.dosomethingelse()

perché non ci sono istanze. Come devo fare in Python per chiamare un metodo statico da un altro metodo statico della stessa classe?

Modifica: che casino. Ok, ho modificato la domanda riportandola alla domanda originale. Ho già la risposta alla seconda domanda che è nel commento di Peter Hansen. Se pensi che dovrei aprire un'altra domanda per una risposta che ho già, per favore dimmelo.


3
@pablo: non puoi cambiare l'essenza della domanda !! Termina questa domanda e iniziane un'altra !!
jldupont

ok ok. vuoi dire eliminare la domanda? La risposta è già lì nel commento di Peter Hansen
Pablo

@pablo: non puoi cancellare qui ciò non sarebbe educato per tutti coloro che hanno contribuito a rispondere alla tua domanda. Devi accettare una risposta e creare una nuova domanda.
jldupont

1
@pablo: e per essere chiari: una risposta dovrebbe essere accettata per la formulazione della tua domanda originale . Non preoccuparti, imparerai come muoverti qui. Saluti :-)
jldupont

Risposte:


77

class.method dovrebbe funzionare.

class SomeClass:
  @classmethod
  def some_class_method(cls):
    pass

  @staticmethod
  def some_static_method():
    pass

SomeClass.some_class_method()
SomeClass.some_static_method()

16
Un consiglio dovrebbe essere aggiunto qui: è chiaro che i metodi di classe non hanno svantaggi rispetto ai metodi statici e i metodi di classe consentono di estendere il metodo in futuro per chiamare altri metodi di classe. Quindi dovrebbe essere sempre preferito, anche se non ce n'è bisogno immediato.
u0b34a0f6ae

1
@ u0b34a0f6ae: Non so se sto facendo qualcosa di buono o no ... ma ho definito un decoratore all'interno di una classe. Il decoratore doveva essere un "metodo statico", non un "metodo di classe".
André Caldas

@ u0b34a0f6ae I metodi di classe sono sempre thread-safe? Nel mio caso d'uso sto usando metodi statici nei thread per impedire l'accesso accidentale alla classe che potrebbe non essere thread-safe.
aquavitae

@ u0b34a0f6ae è sempre un po 'forte. Ad esempio, l'utilizzo di metodi statici PySpark può essere utilizzato nei lavori rdd e i metodi di classe no.
Laurens Koppenol

134

Come devo fare in Python per chiamare un metodo statico da un altro metodo statico della stessa classe?

class Test() :
    @staticmethod
    def static_method_to_call()
        pass

    @staticmethod
    def another_static_method() :
        Test.static_method_to_call()

    @classmethod
    def another_class_method(cls) :
        cls.static_method_to_call()

La chiamata Test.static_method_to_call()dovrebbe funzionare anche da altri metodi non statici e non di classe di questa classe, giusto? (... e probabilmente anche altre classi?)
gr4nt3d

Sì, Test.static_method_to_call()funzionerà da qualsiasi luogo.
warvariuc

11

NOTA: sembra che la domanda sia cambiata. La risposta alla domanda su come chiamare un metodo di istanza da un metodo statico è che non è possibile senza passare un'istanza come argomento o senza creare un'istanza di tale istanza all'interno del metodo statico.

Quello che segue è principalmente per rispondere "come si chiama un metodo statico da un altro metodo statico":

Tenete a mente che non v'è una differenza tra i metodi statici e metodi di classe in Python. Un metodo statico non accetta il primo argomento implicito, mentre un metodo di classe accetta la classe come primo argomento implicito (di solito clsper convenzione). Con questo in mente, ecco come lo faresti:

Se è un metodo statico:

test.dosomethingelse()

Se è un metodo di classe:

cls.dosomethingelse()

1
puoi usare solo cls.dosomethingelse()dall'interno della definizione della classe.
jldupont

3
Per essere più precisi, puoi usare solo cls.dosomethingelse()dall'interno del metodo della classe stesso. Proprio come puoi usare solo selfdall'interno di un metodo di istanza stesso.
Jason Baker

1
scusa, ho scritto erroneamente la domanda. OOPS !. Volevo scrivere "Come devo fare in Python per chiamare un metodo di istanza da un altro metodo statico della stessa classe" e non "Come devo fare in Python per chiamare un metodo statico da un altro metodo statico della stessa class "
Pablo

@pablo: In questo caso, devi scrivere un'altra domanda e finire questa.
jldupont

@jldupont, ho già la risposta ma in un commento. Cosa devo fare perché non posso accettarlo ma sarebbe uno spreco cancellare la domanda, no?
Pablo

4

OK, la principale differenza tra metodi di classe e metodi statici è:

  • Il metodo di classe ha una propria identità, ecco perché devono essere richiamati dall'interno di un'ISTANZA.
  • d'altra parte il metodo statico può essere condiviso tra più istanze in modo che debba essere chiamato dall'interno di THE CLASS

0

non puoi chiamare metodi non statici da metodi statici, ma creando un'istanza all'interno del metodo statico ... dovrebbe funzionare così

class test2(object):
    def __init__(self):
        pass

    @staticmethod
    def dosomething():
        print "do something"
        #creating an instance to be able to call dosomethingelse(),or you may use any existing instace
        a=test2()
        a.dosomethingelse()

    def dosomethingelse(self):
        print "do something else"

test2.dosomething()

spero che ti possa aiutare :)


3
IMO questo approccio è notevolmente peggiore del semplice utilizzo @classmethodper dichiarare i tuoi metodi e dell'uso cls.dosomethingelse()all'interno cls.dosomething()- peggio in termini di prestazioni (istanziare oggetti solo per ottenere l'accesso a un metodo statico) e leggibilità (non è semplice, e immagino se quel tipo del pattern è diventato boilerplate, l'intera codebase potrebbe diventare abbastanza difficile da analizzare per un semplice essere umano)
Kyle Wild

Come ho letto da qualche altra parte in SO, invece di inizializzare direttamente l'istanza per chiamare un metodo, puoi semplicemente chiamarlo: si inizializzerà da solo.
Nakilon

0

Se questi non dipendono dalla classe o dall'istanza, perché non renderli semplicemente una funzione? Poiché questa sembrerebbe la soluzione più ovvia. A meno che, naturalmente, non si pensi che debba essere sovrascritto, sottoclasse ecc. Se è così, allora le risposte precedenti sono la soluzione migliore. Incrociamo le dita non sarò segnato per aver semplicemente offerto una soluzione alternativa che potrebbe o meno soddisfare le esigenze di qualcuno;).

Poiché la risposta corretta dipenderà dal caso d'uso del codice in questione;) Divertiti

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.