Klasy
Stronę tą wyświetlono już: 8488 razy
Najwyższa pora porozmawiać o tym, jak to w Pythonie deklaruje się klasy. Będzie to bardzo dziwaczna opowieść, albowiem sam Python jest dziwacznym językiem programowania. Mimo wszystko słowo kluczowe class na szczęście nawet w Pythonie jest stosowane do deklarowania własnych szablonów klas.
Metody magiczne klas
Magiczne metody są ściśle powiązane z funkcjami lub operatorami. Wszystkie nazwy magicznych metod klas zaczynają się i kończą podwójną dolną spacją (__).
Konstruktor i destruktor klas w Pythonie
Omówię pierwsze Pythonowe dziwactwa, czyli konstruktor i destruktor klasy:
__init__ - konstruktor klasy. Konstruktora, jak i innych metod nie można przeciążać. Każda metoda klasy (w tym również konstruktor jak i destruktor muszą w swej deklaracji przyjmować jako pierwszy argument o nazwie self, który jest etykietą obiektu tej klasy. Co jeszcze bardziej dziwaczne jest, to to, że w konstruktorze deklaruje się pola klasy w sposób następujący: self.nazwa_pola_klasy.
__del__ - destruktor, uruchamiany gdy zostanie wykonane polecenie del na obiekcie klasy.
Oto przykład działania konstruktora i destruktora:
Wynik działania powinien być następujący:
Podaj współrzędną x: 10 Podaj współrzędną y: 20 destruktor uruchomiony destruktor uruchomiony
Rzutowanie
Oto przykład magicznej metody związanej z rzutowaniem obiektu na typ int za pomocą metody magicznej __int__:
Powyższa metoda klasy Point2D oblicza i zwraca całkowitą wartość długości wektora. Oto przykład użycia tej metody:
Wynik działania powyższego kodu:
10
Istnieje też możliwość rzutowania na typ float za pomocą metody magicznej __float__:
Powyższa metoda klasy Point2D oblicza i zwraca zmiennoprzecinkową wartość długości wektora. Oto przykład użycia tej metody:
Wynik działania powyższego kodu:
10.0
Teraz rzutowanie na str poprzez obsługę magicznej metody __str__:
Powyższa metoda klasy Point2D zwraca zmienną tekstową zawierającą współrzędne tego punktu. Oto przykład użycia tej metody:
Wynik działania powyższego kodu:
Point2D(x=10, y=0)
Metoda magiczna __len__
Tę metodę już znamy z list, krotek, słowników i zbiorów. Teraz poznamy jak się ją deklaruje w własnej klasie:
Oto wywołanie tej metody za pomocą funkcji len:
Wynik działania powyższego kodu:
10
Operatory porównania wartości
Obsługa operatorów klas w Pythonie również została zrzucona na barki metod magicznych. W tej części metody związane z obsługą operatorów porównania wartości, czyli:
- __cmp__ - najbardziej kompleksowy operator, obsługuje on wszystkie operatory porównania wartości czyli: <; <=; ==; !=;; >=; >;
- __eq__ - obsługuje operator równości ==;
- __ne__ - obsługuje operator nierówności !=;
- __lt__ - obsługuje operator mniejsze od <;
- __gt__ - obsługuje operator większe od >;
- __le__ - obsługuje operator mniejsze równe <=;
- __ge__ - obsługuje operator większe równe >=.
Oto przykład implementacji metod magicznych dla operatorów porównania wartości związanych z klasą Point2D:
Operatory arytmetyczne
Oto lista operatorów magicznych metod, które odpowiedzialne są za obsługę operatorów arytmetycznych:
- __add__ - dodawanie +;
- __sub__ - odejmowanie -;
- __mul__ - mnożenie *;
- __floordiv__ - dzielenie całkowite //;
- __div__ - dzielenie zmiennoprzecinkowe /;
- __mod__ - reszta z dzielenia %;
- __divmod__ - zwraca część całkowitą i resztę z dzielenia jako krotkę, pod tę metodą podpina się funkcja divmod;
- __pow__ - operator potęgowania **;
- __lshift__ - operator przesunięcia bitowego w lewo <<;
- __rshift__ - operator przesunięcia bitowego w prawo >>;
- __and__ - operator and;
- __or__ - operator or;
- __xor__ - operator xor
W klasie Point2D zastosowanie znajdą tylko niektóre z powyższych operatorów, których przykład implementacji poniżej zamieszczam:
Odwrócone operatory arytmetyczne
Operatory arytmetyczne wcześniej opisane obsługują tylko przypadek następującej postaci:
Nie obsługują natomiast takiego przypadku:
ale, nie ma co płakać, albowiem Pythoniści znaleźli rozwiązanie tego problemu, którym są następujące metody magiczne:
- __radd__ - dodawanie +;
- __rsub__ - odejmowanie -;
- __rmul__ - mnożenie *;
- __rfloordiv__ - dzielenie całkowite //;
- __rdiv__ - dzielenie zmiennoprzecinkowe /;
- __rmod__ - reszta z dzielenia %;
- __rpow__ - operator potęgowania **;
- __rlshift__ - operator przesunięcia bitowego w lewo <<;
- __rrshift__ - operator przesunięcia bitowego w prawo >>;
- __rand__ - operator and;
- __ror__ - operator or;
- __rxor__ - operator xor
W klasie Point2D zastosowanie znajdą tylko niektóre z powyższych operatorów, których przykład implementacji poniżej zamieszczam:
Operatory arytmetyczne z podstawieniem
Przydałoby się jeszcze obsłużyć operatory arytmetyczne z podstawieniem, czyli dla przykładu takie:
I w tym przypadku Pythoniści znaleźli rozwiązanie tego problemu, którym są następujące metody magiczne:
- __iadd__ - dodawanie z podstawieniem +=;
- __isub__ - odejmowanie z podstawieniem -=;
- __imul__ - mnożenie z podstawieniem *=;
- __ifloordiv__ - dzielenie całkowite z podstawieniem //=;
- __idiv__ - dzielenie zmiennoprzecinkowe z podstawieniem /=;
- __imod__ - reszta z dzielenia z podstawieniem %=;
- __ipow__ - operator potęgowania z podstawieniem **=;
- __ilshift__ - operator przesunięcia bitowego w lewo z podstawieniem <<=;
- __irshift__ - operator przesunięcia bitowego w prawo z podstawieniem >>=;
- __iand__ - operator and z podstawieniem &=;
- __ior__ - operator or z podstawieniem |=;
- __ixor__ - operator xor z podstawieniem ^=
W klasie Point2D zastosowanie znajdą tylko niektóre z powyższych operatorów, których przykład implementacji poniżej zamieszczam:
Operatory jednoargumentowe
Oto lista jednoargumentowych metod obsługujących operatory i niektóre funkcje matematyczne:
- __pos__ - jednoargumentowy operator znaku +;
- __neg__ - jednoargumentowy operator znaku -;
- __abs__ - implementacja zachowania funkcji abs;
- __invert__ - implementacja operatora inwersji ~;
- __floor__ - implementacja zachowania funkcji math.floor;
- __ceil__ - implementacja zachowania funkcji math.ceil;
- __trunc__ - implementacja zachowania funkcji math.trunc;
Przykład implementacji co niektórych magicznych metod wyżej wymienionych dla klasy Point2D:
Atrybuty klasy
Kolejnym Pythonowym dziwactwem są atrybuty klasy, które są związane z nazwą klasy a nie z konkretnym obiektem tejże klasy. Zanim jednak pokażę jak tworzy się atrybuty klasy, to najpierw utworze klasę Matrix_tr, która będzie opisywała macierz transformacji:
Teraz wykorzystam klasę Matrix_tr jako atrybut klasy Point2D:
Dostęp atrybutów klasy można osiągnąć na dwa następujące sposoby:
Wynik działania:
| M11 = +1.00000 M12 = 0.00000 dx = +0.00000 | | M21 = +0.00000 M22 = +1.00000 dy = +0.00000 | | M31 = +0.00000 M32 = +0.00000 +1.00000 | Z poziomu obiektu klasy | M11 = +1.00000 M12 = 0.00000 dx = +0.00000 | | M21 = +0.00000 M22 = +1.00000 dy = +0.00000 | | M31 = +0.00000 M32 = +0.00000 +1.00000 |
Co ciekawe, jeżeli zrobię coś takiego:
Wynik działania:
Z poziomu definicji klasy: | M11 = +1.00000 M12 = 0.00000 dx = +0.00000 | | M21 = +0.00000 M22 = +1.00000 dy = +0.00000 | | M31 = +0.00000 M32 = +0.00000 +1.00000 | Z poziomu obiektu klasy: | M11 = +0.50000 M12 = -0.86603 dx = +0.00000 | | M21 = +0.86603 M22 = +0.50000 dy = +0.00000 | | M31 = +0.00000 M32 = +0.00000 +1.00000 |
Jak widać, na powyższym przykładzie, zmiana wartości atrybutu zawartego w danym obiekcie klasy nie zmienia wartości atrybutu definicji klasy.
Własne metody
Tworzenie własnych metod klasy nie różni się znacząco deklaracji metod magicznych. Utwórzmy zatem metodą klasy Point2D w następujący sposób:
Powyższa metoda wykorzystuje atrybut klasy, którym jest macierz transformacji. Macierz ta przemnożona lewostronni przez punkt zwraca punkt, który może zostać obrócony i przesunięty (w zależności od ustawień macierzy transformacji Point2D.tr. Oto przykład użycia tej metody:
Wynik działania:
Point2D(x=100, y=200) Po przesunięciu: Point2D(x=110, y=210) Po przesunięciu i obrócenie o 60 stopni: Point2D(x=-126.86533479473209, y=200.2627944162883)
Jak widać macierz transformacji zapisana jako atrybut klasy Point2D umożliwia przemieszczanie oraz obracanie wszystkich punktów, które zostaną utworzone tak przed, jak i po zmianie macierzy transformacji.
Wykorzystanie klasy Point2D w grafice żółwia
Po lekkiej przeróbce klasy Point2D polegającej na zmianie metody draw można wykorzystać tę klasę do rysowania w omawianej już wcześniej grafice żółwia. Oto kod programu:
Wynikiem działania programu będzie powtarzanie animacji pokazanej na poniższym nagraniu.
Tytuł:
Python w analizie danych. Przetwarzanie danych za pomocą pakietów pandas i NumPy oraz środowiska Jupyter. Wydanie III
Autor:
Wes McKinney
Tytuł:
Machine learning, Python i data science. Wprowadzenie
Autor:
Andreas Müller, Sarah Guido
Tytuł:
Python zorientowany obiektowo. Programowanie gier i graficznych interfejsów użytkownika
Autor:
Irv Kalb
Tytuł:
Python na start! Programowanie dla nastolatków
Autor:
Michał Wiszniewski
Tytuł:
Sztuczna inteligencja w finansach. Używaj języka Python do projektowania i wdrażania algorytmów AI
Autor:
Yves Hilpisch
Tytuł:
Python w zadaniach. Programowanie dla młodzieży. Poziom podstawowy
Autor:
Urszula Wiejak, Adrian Wojciechowski
Tytuł:
Python i praca z danymi. Przetwarzanie, analiza, modelowanie i wizualizacja. Wydanie III
Autor:
Avinash Navlani, Armando Fandango, Ivan Idris
Tytuł:
Black Hat Python. Język Python dla hakerów i pentesterów. Wydanie II
Autor:
Justin Seitz, Tim Arnold
Tytuł:
Python z życia wzięty. Rozwiązywanie problemów za pomocą kilku linii kodu
Autor:
Lee Vaughan
Tytuł:
Python i AI dla e-commerce
Autor:
Sebastian Kondracki