Metody statyczne - jak wywołać metodę z innej metody?

98

Kiedy mam zwykłe metody wywoływania innej metody w klasie, muszę to zrobić

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

ale kiedy mam metody statyczne, nie mogę pisać

self.dosomethingelse()

ponieważ nie ma instancji. Jak mam zrobić w Pythonie, aby wywołać metodę statyczną z innej metody statycznej tej samej klasy?

Edycja: co za bałagan. Ok, zredagowałem pytanie do pierwotnego pytania. Mam już odpowiedź na drugie pytanie w komentarzu Petera Hansena. Jeśli uważasz, że powinienem otworzyć inne pytanie, aby uzyskać odpowiedź, którą już mam, proszę, powiedz mi.

Pablo
źródło
3
@pablo: nie możesz zmienić istoty pytania !! Zakończ to pytanie i zacznij następne !!
jldupont,
ok ok. czy masz na myśli usunięcie pytania? Odpowiedź jest już w komentarzu Petera Hansena
Pablo
@pablo: nie możesz tutaj usunąć, co byłoby niegrzeczne dla wszystkich, którzy udzielili odpowiedzi na Twoje pytanie. Musisz zaakceptować odpowiedź i utworzyć nowe pytanie.
jldupont,
1
@pablo: i żeby było jasne: odpowiedź powinna zostać zaakceptowana dla twojego pierwotnego sformułowania pytania. Nie martw się, nauczysz się tu poruszać. Pozdrawiam :-)
jldupont

Odpowiedzi:

80

class.method powinno działać.

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

  @staticmethod
  def some_static_method():
    pass

SomeClass.some_class_method()
SomeClass.some_static_method()
jldupont
źródło
17
W tym miejscu należy dodać radę: Jest oczywiste, że metody klasowe nie mają żadnych wad w porównaniu z metodami statycznymi, a metody klasowe pozwalają w przyszłości rozszerzyć metodę o wywołanie innych metod klasowych. Dlatego zawsze powinno być preferowane, nawet jeśli nie ma natychmiastowej potrzeby.
u0b34a0f6ae
1
@ u0b34a0f6ae: Nie wiem, czy robię coś dobrego, czy nie ... ale zdefiniowałem dekoratora w klasie. Dekorator musiał być „metodą statyczną”, a nie „metodą klasową”.
André Caldas
@ u0b34a0f6ae Czy metody klasowe są jednak zawsze bezpieczne dla wątków? W moim przypadku używam staticmethods w wątkach, aby zapobiec przypadkowemu dostępowi do klasy, która może nie być bezpieczna dla wątków.
aquavitae,
@ u0b34a0f6ae zawsze jest trochę mocne. Na przykład użycie metod statycznych PySpark może być używane w zadaniach rdd, a metody klas nie mogą.
Laurens Koppenol
140

Jak mam zrobić w Pythonie, aby wywołać metodę statyczną z innej metody statycznej tej samej klasy?

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
źródło
Wywołanie Test.static_method_to_call()powinno działać również z innych niestatycznych i nieklasowych metod tej klasy, prawda? (... i prawdopodobnie inne zajęcia?)
gr4nt3d
Tak, Test.static_method_to_call()będzie działać z dowolnego miejsca.
warvariuc
11

UWAGA - wygląda na to, że pytanie trochę się zmieniło. Odpowiedź na pytanie, jak wywołać metodę instancji z metody statycznej, jest taka, że ​​nie można tego zrobić bez przekazania instancji jako argumentu lub bez utworzenia jej instancji wewnątrz metody statycznej.

Poniżej znajduje się głównie odpowiedź na pytanie „jak wywołać metodę statyczną z innej metody statycznej”:

Należy pamiętać, że jest różnica między metody statyczne i metody klasy w Pythonie. Metoda statyczna nie przyjmuje niejawnego pierwszego argumentu, podczas gdy metoda klasowa przyjmuje klasę jako niejawny pierwszy argument (zwykle clszgodnie z konwencją). Mając to na uwadze, oto jak możesz to zrobić:

Jeśli jest to metoda statyczna:

test.dosomethingelse()

Jeśli jest to metoda klasowa:

cls.dosomethingelse()
Jason Baker
źródło
1
możesz używać tylko cls.dosomethingelse()z definicji klasy.
jldupont,
3
Aby być dokładniejszym, możesz używać tylko cls.dosomethingelse()z poziomu samej metody klasy. Tak jak możesz używać tylko selfz poziomu samej metody instancji.
Jason Baker
1
przepraszam, źle napisałem pytanie. Ups !. Chciałem napisać "Co mam zrobić w Pythonie, aby wywołać metodę instancji z innej metody statycznej tej samej klasy", a nie "Jak mam zrobić w Pythonie, aby wywołać metodę statyczną z innej metody statycznej tej samej class ”
Pablo
@pablo: W takim przypadku musisz napisać kolejne pytanie i dokończyć to.
jldupont
@jldupont, mam już odpowiedź, ale w jednym komentarzu. Co powinienem zrobić, ponieważ nie mogę tego zaakceptować, ale wymazanie pytania byłoby marnotrawstwem, prawda?
Pablo
4

OK, główna różnica między metodami klasowymi a metodami statycznymi to:

  • class ma swoją własną tożsamość, dlatego muszą być wywoływane z INSTANCE.
  • z drugiej strony metoda statyczna może być współdzielona między wieloma instancjami, więc musi być wywoływana z poziomu THE CLASS
Ahmad Dwaik
źródło
Nie wydaje się to właściwe - ale znaczenie tutaj jest niejasne bez przykładu, więc trudno powiedzieć. Przede wszystkim „metody klasowe” nie muszą być wywoływane „z poziomu instancji”… możesz wywoływać MyClass.class_method()z dowolnego miejsca MyClass(może myślałeś o „metodach instancji”?)
mltsy
1

Jeśli nie zależą one od klasy lub instancji, dlaczego nie uczynić ich po prostu funkcją? Ponieważ wydaje się to oczywistym rozwiązaniem. O ile oczywiście nie myślisz, że będzie to wymagało nadpisania, podklasy itp. Jeśli tak, to poprzednie odpowiedzi są najlepszym rozwiązaniem. Trzymam kciuki Nie zostanę skrytykowany za oferowanie jedynie alternatywnego rozwiązania, które może, ale nie musi odpowiadać czyimś potrzebom;).

Ponieważ prawidłowa odpowiedź będzie zależała od przypadku użycia danego kodu;) Enjoy

AppHandwerker
źródło
0

nie możesz wywoływać metod niestatycznych z metod statycznych, ale tworząc instancję wewnątrz metody statycznej ... powinno to tak działać

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

mam nadzieję, że ci to pomoże :)

Ahmad Dwaik
źródło
3
IMO to podejście jest znacznie gorsze niż zwykłe @classmethodzadeklarowanie metod i użycie cls.dosomethingelse()wewnątrz cls.dosomething()- gorsze zarówno pod względem wydajności (tworzenie instancji obiektów tylko po to, aby uzyskać dostęp do metody statycznej), jak i czytelności (nie jest to proste i wyobrażam sobie, wzorca stał się szablonem, cała podstawa kodu może stać się dość trudna do przeanalizowania dla zwykłego człowieka)
Kyle Wild
Jak czytałem gdzie indziej w SO, zamiast bezpośrednio inicjować instancję w celu wywołania metody, możesz ją po prostu wywołać - zainicjuje ona sama.
Nakilon