Podczas integracji aplikacji Django, której wcześniej nie używałem, znalazłem dwa różne sposoby definiowania funkcji w klasach. Autor wydaje się używać ich obu bardzo celowo. Pierwszy to ten, którego sam często używam:
class Dummy(object):
def some_function(self,*args,**kwargs):
do something here
self is the class instance
Drugi to taki, którego nie używam, głównie dlatego, że nie rozumiem, kiedy go używać i do czego:
class Dummy(object):
@classmethod
def some_function(cls,*args,**kwargs):
do something here
cls refers to what?
W dokumentacji Pythona classmethod
dekorator jest wyjaśniony następującym zdaniem:
Metoda klasy otrzymuje klasę jako niejawny pierwszy argument, tak jak metoda instancji otrzymuje instancję.
Więc myślę, że cls
odnosi się do Dummy
siebie (a class
nie do instancji). Nie do końca rozumiem, dlaczego tak jest, ponieważ zawsze mogłem to zrobić:
type(self).do_something_with_the_class
Czy to tylko dla jasności, czy też przegapiłem najważniejszą część: straszne i fascynujące rzeczy, których nie można by zrobić bez tego?
self.foo()
kiedy powinnoBar.foo()
.self.foo()
jest preferowany, ponieważself
może być instancją podklasy, która implementuje własnąfoo
.Bar
, as1+1 == 2 == 1*2
, więc na podstawie wyświetlonych wyników nie można stwierdzić, żeBar().static_method
faktycznie jest nazywana.Zasadniczo powinieneś użyć @classmethod, gdy zdasz sobie sprawę, że definicja metody nie zostanie zmieniona ani zastąpiona.
Dodatkowo: teorycznie metody klasowe są szybsze niż metody obiektowe, ponieważ nie wymagają tworzenia instancji i wymagają mniej pamięci.
źródło
Jeśli dodasz dekorator @classmethod, oznacza to, że zamierzasz utworzyć tę metodę jako metodę statyczną w Javie lub C ++. (Metoda statyczna jest ogólnym terminem Chyba ;) ) Pythona ma również @staticmethod. a różnica między classmethod i staticmethod polega na tym, czy możesz uzyskać dostęp do klasy lub zmiennej statycznej za pomocą argumentu lub samej nazwy klasy.
class TestMethod(object): cls_var = 1 @classmethod def class_method(cls): cls.cls_var += 1 print cls.cls_var @staticmethod def static_method(): TestMethod.cls_var += 1 print TestMethod.cls_var #call each method from class itself. TestMethod.class_method() TestMethod.static_method() #construct instances testMethodInst1 = TestMethod() testMethodInst2 = TestMethod() #call each method from instances testMethodInst1.class_method() testMethodInst2.static_method()
wszystkie te klasy zwiększają cls.cls_var o 1 i wyświetlają go.
I wszystkie klasy używające tej samej nazwy w tym samym zakresie lub instancjach skonstruowanych z tą klasą będą współdzielić te metody. Jest tylko jeden TestMethod.cls_var, a także jest tylko jeden TestMethod.class_method (), TestMethod.static_method ()
I ważne pytanie. dlaczego ta metoda byłaby potrzebna.
classmethod lub staticmethod są przydatne, gdy tworzysz tę klasę jako fabrykę lub gdy musisz zainicjować swoją klasę tylko raz. jak raz otwórz plik i używając metody feed, aby odczytać plik wiersz po wierszu.
źródło