W Pythonie metody występują w trzech głównych typach: metody instancji, metody klasowe i metody statyczne. Historycznie Python wspierał tylko metody instancji (z pierwszym parametrem self). Z czasem pojawiła się potrzeba dodatkowych typów metod: dostępnych przez klasę bez powiązania z obiektem i z dostępem do samej klasy.
Problem: często potrzebne są metody, które nie zależą od stanu instancji obiektu (na przykład metody fabryczne) lub które nie potrzebują kontekstu klasy, ale logicznie wchodzą w strukturę klasy.
Rozwiązanie: używane są dekoratory @classmethod i @staticmethod.
Przykład kodu:
class Example: def instance_method(self): return f'instancja: {self}' @classmethod def class_method(cls): return f'klasa: {cls}' @staticmethod def static_method(): return 'statyczna'
Kluczowe cechy:
Czy metoda statyczna może odnosić się do atrybutów klasy i instancji?
Nie, metoda statyczna nie otrzymuje odniesienia ani do klasy, ani do obiektu.
class A: x = 10 @staticmethod def f(): # print(self.x) # Błąd pass
Czy metody klasowe mogą być nadpisywane w klasach pochodnych?
Tak, przy wywoływaniu classmethod przez potomka, pierwszym argumentem zawsze będzie faktyczna klasa, a nie rodzic.
class Base: @classmethod def name(cls): return cls.__name__ class Child(Base): pass Child.name() # "Child"
Dlaczego nie można używać self w metodach klasowych?
Ponieważ metoda klasowa nie jest powiązana z konkretnym obiektem, a z klasą jako całością; self nie jest dostępne bez stworzenia instancji.
Metoda fabryczna została zdefiniowana jako staticmethod, a wewnątrz próbuje się stworzyć instancję klasy przez self, co prowadzi do błędów lub duplikacji kodu.
Zalety:
Wady:
Fabryka została zadeklarowana przez classmethod, wewnątrz używany jest faktyczny klasa (cls) do tworzenia instancji. Potomkowie są poprawnie tworzeni przez tę fabrykę.
Zalety:
Wady: