Metody statyczne i metody klasy

https://docs.python.org/3/library/functions.html

WPROWADZENIE

Metody statyczne są opcją dodaną w Pythonie 2.2. Pozwalają one zapisywać w kodzie klasy funkcje nieoczekujące podania obiektów instancji w pierwszym argumencie. Takie metody mogą działać jak proste funkcje bez instancji, ich nazwy są lokalne dla klas, w których są zapisane. Metody statyczne mogą być wykorzystane do zarządzania danymi klas.

Do tych zadań można byłoby wykorzystać zwykłe funkcje zdefiniowane poza klasą, które mają dostęp do atrybutów klasy za pośrednictwem nazwy klasy. Jednak dzięki powiązaniu z klasą można lepiej podzielić kod programu oraz można korzystać z dziedziczenia.

Metody klasy jako pierwszy argument mają obiekt klasy (cls), a nie obiekt instancji (self). Metodę klasy można użyć do budowy dodatkowego konstruktora.


class Methods:

    def imeth(self, x):   # zwykła metoda instancji
        # Pierwszy argument to zwyczajowo self (bieżąca instancja).
        print("{} {}".format(self, x))

    def smeth(x):         # metoda statyczna
        # Pierwszy argument to nie jest self.
        print(x)

    def cmeth(cls, x):    # metoda klasy
        # Pierwszy argument tradycyjnie nazywamy cls, a nie self.
        # cls to obiekt klasy (tutaj to klasa Methods).
        print("{} {}".format(cls, x))

    smeth = staticmethod(smeth)   # przekształcanie
    cmeth = classmethod(cmeth)    # przekształcanie

# Zastosowanie.
item = Methods()
item.imeth(1)                 # <__main__.Methods instance at 0xb739546c> 1
Methods.imeth(item, 2)        # <__main__.Methods instance at 0xb739546c> 2

# Przy metodach statycznych i metodach klas nie musi istnieć instancja klasy.
Methods.smeth(3)              # 3
item.smeth(4)                 # 4

Methods.cmeth(5)              # __main__.Methods 5
item.cmeth(6)                 # __main__.Methods 6

Do utworzenia metod statycznych i metod klasy można użyć dekoratorów metod.


class Methods:

    @staticmethod   # składnia dekoratora
    def smeth(x): pass

    @classmethod   # składnia dekoratora
    def cmeth(cls, x): pass

PRZYKŁAD


class Frac:

    @staticmethod
    def gcd(m, n):   # algorytm Euklidesa
        if m % n == 0:
            return n
        else:
            return Frac.gcd(n, m % n)

assert Frac.gcd(6, 4) == 2

class Poly:

    def __init__(self, coefficient=0, n=0):
        # Na bazie Sedgewicka - tworzymy wielomian c*(x**n).
        self.size = n + 1   # rozmiar tablicy
        self.data = self.size * [0]
        self.data[self.size - 1] = coefficient

    @classmethod
    def from_iterable(cls, iterable):   # dodatkowy konstruktor
        new_poly = cls()   # działa zwykły konstruktor
        new_poly.data = list(iterable)
        new_poly.size = len(new_poly.data)
        return new_poly

assert Poly.from_iterable([0, 3, 5]) == Poly(3, 1) + Poly(5, 2)