Ten artykuł podkreśla obowiązkowe metody specjalne Pythona, które każdy programista Pythona musi znać
Metody magiczne pomagają nam wzbogacić nasze aplikacje. Pośrednio dodają magii do naszego kodu Pythona. Jest to temat na poziomie zaawansowanym dla programistów Pythona i polecam go każdemu, kto używa/zamierza używać języka programowania Python.
Metody magiczne dają nam większą kontrolę nad tym, jak zachowuje się nasza aplikacja.
Ten artykuł ma na celu wyjaśnienie, czym są metody magiczne i jak można je wykorzystać do budowania aplikacji w Pythonie. Przedstawi on przegląd najczęściej używanych metod magicznych dla różnych typów danych.
Celem nakreślenia kluczowych metod magicznych jest zrozumienie, czy chcemy nadpisać te metody w naszych niestandardowych klasach, aby wzbogacić aplikacje.
Metody magiczne czynią język programowania Python niezwykle potężnym
What Are The Python Magic Methods?
Metody magiczne Pythona są również znane jako metody specjalne lub metody dunder. Są one otoczone podwójnymi podkreślnikami, np. __init__().
Obiekt może mieć wiele metod magicznych.
Pamiętaj, że wszystko w Pythonie jest obiektem, w tym zmienna/funkcja/klasa itd. Obiekty są abstrakcją Pythona dla danych.
Metody magiczne są używane do konstruowania i inicjalizowania nowych obiektów, pomagają nam odzyskać obiekt jako słownik, są używane do usuwania obiektu wśród innych operacji. Są używane, gdy wywoływany jest operator +, a nawet gdy chcemy reprezentować obiekt jako ciąg znaków.
Chociaż każda metoda w Pythonie jest publiczna, konwencją kodowania jest otaczanie wszystkich metod prywatnych podwójnymi podkreślnikami __<metoda>__()
To sugeruje, że metody magiczne są przeznaczone do bycia metodami prywatnymi. Oznacza to również, że wywołujący obiekt nie powinien wywoływać tej metody bezpośrednio, ponieważ metoda ta ma być wywoływana przez klasę wewnętrznie posiadającą metodę magiczną.
Możemy nadpisać metody magiczne, aby zapewnić własną funkcjonalność.
Wyjaśnię koncepcje metod magicznych poprzez stworzenie klasy niestandardowej, a następnie przedstawię przegląd najważniejszych metod magicznych w liczbie całkowitej, łańcuchu, liście i słowniku.
W miarę postępów w dół artykułu, zacznie budować znacznie jaśniejszy obraz tego, dlaczego metody magiczne istnieją i jak z nich korzystać.
Jeśli chcesz zrozumieć język programowania Python od poziomu początkującego do zaawansowanego, to gorąco polecam poniższy artykuł:
Zacznę temat metod magicznych od stworzenia klasy niestandardowej, a następnie wyjaśnię, jak są używane metody magiczne.
Przypadek użycia do zrozumienia metod magicznych
W poniższym snippecie utworzyłem klasę o nazwie Human, a następnie stworzyłem instancję klasy Human.
Ten fragment kodu posłuży nam do zrozumienia metod magicznych.
Zauważ, że id obiektu Human jest typu całkowitego, atrybut name jest typu string, właściwość addresses jest typu listowego, a właściwość maps jest typu słownikowego.
Dla ułatwienia czytania pogrupowałem metody magiczne w różne sekcje typów danych. Jednak te same metody magiczne znajdują się w różnych typach danych.
Metody magiczne mogą zostać nadpisane w celu wzbogacenia funkcjonalności i stworzenia niestandardowej logiki, która najlepiej odpowiada potrzebom biznesowym.
Klasa:
Zrozummy metody magiczne, które są związane z obiektem człowiek. Jeśli wykonam metodę dir(human), wyświetli ona listę wszystkich funkcji i nazw atrybutów obiektu human.
Istnieje w sumie 29 metod/atrybutów, które są związane z obiektem human. Wśród nich 26 to metody magiczne.
To całkiem spora liczba metod specjalnych. Metody te są dziedziczone z typu bazowego klasy Human. Stąd są to predefiniowane metody, których możemy używać/override w celu wzbogacenia klas.
W następnej części rozdziału wyjaśnimy kluczowe metody magiczne.
__delattr__
Ta metoda jest wywoływana, gdy próbujemy usunąć atrybut z klasy.
Możemy nadpisać tę funkcjonalność, implementując metodę w klasie Human:
def __delattr__(self, item):
print('Deleting attribute ' + item)
return object.__delattr__(self, item)
Teraz, przy każdej próbie usunięcia atrybutu, będzie ona wyświetlała komunikat: Usuwanie atrybutu
Istnieje również metoda __setattr__() do przypisania wartości do atrybutu oraz __getattr__() do uzyskania wartości z atrybutu.
Przypadkiem użycia metody __delattr__() może być uniemożliwienie usunięcia poszczególnych atrybutów obiektu lub gdy chcemy wykonać określone akcje, gdy dany atrybut zostanie usunięty.
__dict__
Metoda ta zwraca słownik reprezentujący obiekt. Klucze słownika to atrybuty obiektu, a wartości to wartości atrybutów.
Jako instancja:
human = Human(2, 'Malik').__dict__
print(human)
Powyższy kod zwraca:
{’id’: 2, 'name’: 'Malik’, 'addresses’: , 'maps’: {}}
__dir__
Możemy nadpisać metodę dir() poprzez nadpisanie metody __dir__() w klasie. Jako przykład, możemy usunąć wewnętrzne metody z wyniku zwracanego przez metodę dir():
__eq__
Ta metoda jest wywoływana, gdy próbujemy wykonać operację ==. Rozważmy, że dwa obiekty ludzkie są równe, gdy ich atrybut id jest równy, nawet jeśli ich nazwy są różne.
Możemy nadpisać metodę __eq__(), aby osiągnąć tę funkcjonalność:
def __eq__(self, other):
return self.id == other.id
Ta metoda będzie teraz zwracać True:
first = Human(1, 'Farhad')
second = Human(1, 'Malik')
print(first == second)
__format__
Kiedy próbujemy wykonać string.format(), metoda __format__() jest wywoływana wewnętrznie.
__ge__
Jako przykład załóżmy, że istnieją dwa obiekty typu Human:
first = Human(1, 'Farhad')
second = Human(2, 'Malik')
Zastanówmy się również, że nasz projekt ma zasadę, że obiekt typu Human z większym Id jest uważany za większy niż drugi obiekt typu Human. Dlatego możemy nadpisać metodę __gt__() i zaimplementować niestandardową logikę:
def __ge__(self, other):
return self.id >= other.id
Teraz zwróci ona False, ponieważ id drugiego obiektu ludzkiego jest większe niż pierwszego obiektu ludzkiego:
print(first >= second)
Returns False
Istnieje również metoda __lt__(), która jest wykonywana, gdy wykonywany jest operator ≤.
__hash__
Hashing jest używany do konwersji obiektu na liczbę całkowitą. Haszowanie jest wykonywane, gdy próbujemy ustawić element w słowniku/zestawie.
Dobry algorytm haszowania powoduje mniejszą liczbę kolizji haszowania. Możemy dostarczyć nasz własny algorytm haszujący poprzez nadpisanie metody __hash__().
Zastanówmy się, że id obiektu Human ma być unikalne w naszej aplikacji. Algorytm __hash__() może zostać nadpisany, aby zwrócić self.id jako liczbę całkowitą hash:
def __hash__(self):
return self.id
Możemy utworzyć dwa obiekty i zapisać je w kolekcji set. Kiedy zapytamy o długość zestawu, będziemy oczekiwać dwóch elementów w zestawie, ponieważ oba obiekty mają różne id.
first = Human(1, 'Farhad')
second = Human(2, 'Malik')
my_set = set()
print(len(my_set))
#returns 2
Jeśli teraz ustawimy id na 1 dla obu obiektów i powtórzymy ćwiczenie, wtedy zobaczymy tylko 1 element w zestawie, ponieważ oba obiekty mają ten sam klucz hash, ponieważ ich atrybut id jest taki sam, mimo że ich atrybut name jest inny.
first = Human(1, 'Farhad')
second = Human(1, 'Malik')
my_set = set()
print(len(my_set))
#returns 1
__init__
Metoda __init__() jest wykonywana, gdy chcemy zainicjować nową instancję klasy poprzez wywołanie jej konstruktora.
Jako instancja, gdy próbowaliśmy wykonać:
human = Human(1, 'farhad')
Wtedy została wykonana metoda __init__().
Możemy nadpisać tę funkcjonalność i przekazać w niej również nasze własne niestandardowe argumenty i zachowanie.
Jako instancja, metoda __init__() klasy Human to:
def __init__(self, id, name, addresses=, maps={}):
self.id = id
self.name = name
self.addresses = addresses
self.maps = maps
__init_subclass__
Jest to jeden z przypadków użycia metaklasy. Kiedy klasa jest podklasowana i jej obiekt jest tworzony, wtedy wywoływana jest metoda __init_subclass__().
Podstawowo, metoda informuje rodzica, że została podklasowana. Ten hak może następnie zainicjalizować wszystkie podklasy danej klasy. Metoda ta służy więc do rejestrowania podklas i przypisywania domyślnych wartości do atrybutów w podklasach. Stąd, pozwala nam to na dostosowanie inicjalizacji podklas.
Wyjaśnię jak działają metaklasy w moim następnym artykule.
__new__
Gdy chcemy zainicjować/stworzyć nową instancję klasy wtedy wykonywana jest metoda __new__(cls).
Jako instancję rozważmy, że chcemy wypisać 'Człowiek tworzący…’ za każdym razem, gdy wywoływany jest konstruktor Human().
Możemy nadpisać funkcjonalność metody __new__(cls), jak pokazano poniżej:
def __new__(cls, *args, **kwargs):
print('Human creating...')
return object.__new__(cls)
W rezultacie, Human creating… jest wypisywany, gdy próbujemy utworzyć instancję:
human = Human(1, 'Farhad', , {'London':2, 'UK':3})
__sizeof__
Ta metoda jest wywoływana, gdy wykonujemy sys.getsizeof(). Zwraca ona rozmiar obiektu w pamięci, w bajtach.
__str__
Wyświetliła: id=1. name=Farhad.
Funkcja __str__() powinna próbować zwrócić przyjazną dla użytkownika reprezentację obiektu.
__weakref__
Ten obiekt __weakref__ zwraca listę słabych referencji do obiektu docelowego. Zasadniczo pomaga odśmiecaniu poinformować słabe referencje, że referent został zebrany. W związku z tym uniemożliwia obiektom dostęp do bazowych wskaźników.
Podsumowanie
To jest temat na poziomie zaawansowanym dla programistów Pythona i polecam go każdemu, kto używa/ lub zamierza używać języka programowania Python.
Ten artykuł miał na celu wyjaśnienie, czym są metody magiczne i jak można ich używać do budowania aplikacji w Pythonie. Zawierał przegląd najczęściej używanych metod magicznych w klasie niestandardowej, liczb całkowitych, łańcuchów, list i słownikowych typów danych.
Pomimo że każda metoda w Pythonie jest publiczna, konwencją kodowania jest otaczanie wszystkich metod prywatnych podwójnym podkreśleniem __<metoda>__()
To sugeruje, że metody magiczne mają być metodami prywatnymi. Oznacza to również, że wywołujący obiekt nie powinien bezpośrednio wywoływać tej metody, a metoda jest wywoływana wewnętrznie przez klasę, która posiada metodę magiczną. Metody magiczne pozwalają nam mieć większą kontrolę nad tym, jak zachowuje się nasza aplikacja.
Metody magiczne mogą być nadpisane, aby wzbogacić funkcjonalność i stworzyć niestandardową logikę, która najlepiej odpowiada potrzebom biznesowym.
Celem nakreślenia kluczowych metod magicznych jest dla nas zrozumienie, czy chcemy nadpisać te metody w naszych niestandardowych klasach, aby wzbogacić aplikacje.
.