Statische Methoden - Wie rufe ich eine Methode von einer anderen Methode auf?

95

Wenn ich reguläre Methoden zum Aufrufen einer anderen Methode in einer Klasse habe, muss ich dies tun

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

aber wenn ich statische Methoden habe, kann ich nicht schreiben

self.dosomethingelse()

weil es keine Instanz gibt. Wie muss ich in Python vorgehen, um eine statische Methode von einer anderen statischen Methode derselben Klasse aufzurufen?

Edit: was für ein Durcheinander. Ok, ich habe die Frage auf die ursprüngliche Frage zurückgesetzt. Ich habe bereits die Antwort auf die zweite Frage in Peter Hansens Kommentar. Wenn Sie denken, ich sollte eine andere Frage für eine Antwort öffnen, die ich bereits habe, sagen Sie mir bitte.

Pablo
quelle
3
@pablo: du kannst das Wesentliche der Frage nicht ändern !! Beende diese Frage und beginne eine andere !!
Jldupont
OK OK. Meinst du die Frage löschen? Die Antwort ist bereits in Peter Hansens Kommentar enthalten
Pablo
@pablo: Sie können hier nicht löschen, was nicht für alle höflich wäre, die Antworten auf Ihre Frage beigetragen haben. Sie müssen eine Antwort akzeptieren und eine neue Frage erstellen.
Jldupont
1
@pablo: und um ganz klar zu sein: Eine Antwort sollte für Ihre ursprüngliche Frageformulierung akzeptiert werden . Mach dir keine Sorgen, du wirst dich hier zurechtfinden. Prost :-)
jldupont

Antworten:

77

class.method sollte arbeiten.

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

  @staticmethod
  def some_static_method():
    pass

SomeClass.some_class_method()
SomeClass.some_static_method()
jldupont
quelle
16
Hier sollte ein Hinweis hinzugefügt werden: Es ist klar, dass Klassenmethoden keine Nachteile gegenüber statischen Methoden haben, und Klassenmethoden ermöglichen es, die Methode in Zukunft zu erweitern, um andere Klassenmethoden aufzurufen. Daher sollte es immer bevorzugt werden, auch wenn keine unmittelbare Notwendigkeit besteht.
u0b34a0f6ae
1
@ u0b34a0f6ae: Ich weiß nicht, ob ich etwas Gutes tue oder nicht ... aber ich habe einen Dekorateur innerhalb einer Klasse definiert. Der Dekorateur musste eine "statische Methode" sein, keine "Klassenmethode".
André Caldas
@ u0b34a0f6ae Sind Klassenmethoden jedoch immer threadsicher? In meinem Anwendungsfall verwende ich statische Methoden in Threads, um einen versehentlichen Zugriff auf die Klasse zu verhindern, die möglicherweise nicht threadsicher ist.
Aquavitae
@ u0b34a0f6ae ist immer ein bisschen stark. Beispielsweise kann die Verwendung von PySpark staticmethods in rdd-Jobs verwendet werden und classmethods nicht.
Laurens Koppenol
134

Wie muss ich in Python vorgehen, um eine statische Methode von einer anderen statischen Methode derselben Klasse aufzurufen?

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()
warvariuc
quelle
Der Aufruf Test.static_method_to_call()sollte auch mit anderen nicht statischen und nicht klassenbezogenen Methoden dieser Klasse funktionieren, oder? (... und wahrscheinlich auch andere Klassen?)
gr4nt3d
Ja, Test.static_method_to_call()wird von überall funktionieren.
Warvariuc
11

HINWEIS - anscheinend hat sich die Frage geändert. Die Antwort auf die Frage, wie Sie eine Instanzmethode von einer statischen Methode aus aufrufen, lautet, dass Sie dies nicht können, ohne eine Instanz als Argument zu übergeben oder diese Instanz innerhalb der statischen Methode zu instanziieren.

Was folgt, ist hauptsächlich die Antwort "Wie ruft man eine statische Methode von einer anderen statischen Methode auf":

Beachten Sie, dass es ist ein Unterschied zwischen statischen Methoden und Klassenmethoden in Python. Eine statische Methode verwendet kein implizites erstes Argument, während eine Klassenmethode die Klasse als implizites erstes Argument verwendet (normalerweise clsgemäß Konvention). In diesem Sinne würden Sie das folgendermaßen tun:

Wenn es sich um eine statische Methode handelt:

test.dosomethingelse()

Wenn es eine Klassenmethode ist:

cls.dosomethingelse()
Jason Baker
quelle
1
Sie können nur cls.dosomethingelse()innerhalb der Klassendefinition verwenden.
Jldupont
3
Um genauer zu sein, können Sie nur cls.dosomethingelse()innerhalb der Klassenmethode selbst verwenden. Genau wie Sie nur selfinnerhalb einer Instanzmethode selbst verwenden können.
Jason Baker
1
Entschuldigung, ich habe die Frage falsch geschrieben. HOPPLA!. Ich wollte schreiben "Wie muss ich in Python vorgehen, um eine Instanzmethode von einer anderen statischen Methode derselben Klasse aufzurufen?" Und nicht "Wie muss ich in Python vorgehen, um eine statische Methode von einer anderen statischen Methode derselben Klasse aufzurufen?" Klasse "
Pablo
@pablo: In diesem Fall müssen Sie eine weitere Frage schreiben und diese beenden.
Jldupont
@jldupont, ich habe bereits die Antwort aber in einem Kommentar. Was soll ich tun, weil ich es nicht akzeptieren kann, aber es wäre eine Verschwendung, die Frage zu löschen, nicht wahr?
Pablo
4

OK, der Hauptunterschied zwischen Klassenmethoden und statischen Methoden ist:

  • Die Klassenmethode hat ihre eigene Identität, deshalb müssen sie aus einer INSTANZ heraus aufgerufen werden.
  • Andererseits kann die statische Methode von mehreren Instanzen gemeinsam genutzt werden, sodass sie innerhalb von THE CLASS aufgerufen werden muss
Ahmad Dwaik
quelle
0

Sie können nicht statische Methoden nicht von statischen Methoden aufrufen, aber indem Sie eine Instanz innerhalb der statischen Methode erstellen ... sollte dies so funktionieren

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()

hoffe das hilft dir :)

Ahmad Dwaik
quelle
3
IMO ist dieser Ansatz deutlich schlechter als nur @classmethoddas Deklarieren Ihrer Methoden und das Verwenden von cls.dosomethingelse()inside cls.dosomething()- schlechter in Bezug auf Leistung (Instanziieren von Objekten, nur um Zugriff auf eine statische Methode zu erhalten) und Lesbarkeit (es ist nicht einfach, und ich stelle mir vor, ob dies der Fall ist von Muster wurde Boilerplate, die gesamte Codebasis könnte für einen bloßen Menschen ziemlich schwierig zu analysieren werden)
Kyle Wild
Wie ich an einer anderen Stelle bei SO gelesen habe, können Sie die Instanz nicht direkt initialisieren, um eine Methode aufzurufen, sondern sie einfach aufrufen - sie wird sich selbst initiieren.
Nakilon
0

Wenn diese nicht von der Klasse oder Instanz abhängen, warum machen Sie sie dann nicht einfach zu einer Funktion? Da scheint dies die naheliegende Lösung zu sein. Es sei denn, Sie glauben natürlich, dass es überschrieben werden muss, Unterklasse usw. Wenn ja, dann sind die vorherigen Antworten die beste Wahl. Daumen drücken Ich werde nicht dafür markiert, dass ich nur eine alternative Lösung anbiete, die möglicherweise den Bedürfnissen eines Menschen entspricht oder nicht;).

Da die richtige Antwort vom Anwendungsfall des betreffenden Codes abhängt;) Viel Spaß

AppHandwerker
quelle