Twórz bez wysiłku klasy w Pythonie za pomocą @dataclass
W Pythonie @dataclassdekorator upraszcza proces tworzenia klas, automatycznie dodając wspólne metody i promując najlepsze praktyki pisania dobrze napisanego i bezpiecznego kodu. Jest dostępny od Pythona 3.7. W tym artykule opowiem o tym dekoratorze.
Zacznijmy od prostego przykładu:
Definiując dwie zmienne statyczne ze wskazówkami typu i dodając dekorator @dataclass, otrzymujemy klasę z __init__metodą odpowiadającą następującemu:
Chociaż pomijanie __init__metody - jest przyjemne, klasa danych oferuje znacznie więcej niż tylko to. Aby to zrozumieć, spójrzmy na opcje dostępne dla dekoratora:
Pominąłem niektóre argumenty i pozostawiłem te, które uważam za najważniejsze do przedyskutowania. Pamiętaj, że używając:
równoważnie spowoduje użycie domyślnych argumentów.
Jak widać, w zależności od argumentów, metody zostaną dodane do klasy niejawnie. Domyślnie:
- init=True doda,
__init__jak widzieliśmy powyżej - repr=True doda
__repr__, czyli to, co jest pokazane podczas drukowania - eq=True doda
__eq__na podstawie pól - order=True doda
__lt__(),__le__(),__gt__(), i__ge__()
Zauważ, że możesz oczywiście zdefiniować inne niestandardowe metody klasowe, tak jak zwykle w klasie. Poniżej definiuję prostą klasę bez dekoratora @dataclass dla porównania.
Druk
Z repr=True, które jest ustawione domyślnie, dane wyjściowe podczas drukowania są zmieniane. Porównajmy, co obiekt utworzony z klasą danych i obiekt utworzony z normalną klasą (bez __repr__) pokazuje się po wydrukowaniu:
Jak widać w przypadku normalnej klasy, wydrukowane informacje domyślnie mówią nam bardzo niewiele o obiekcie. Z drugiej strony dataclass pokazuje zwięźle wartości obiektu, zastępując domyślną __repr__metodę -.
Równość
Domyślne zachowanie równości dla klas niestandardowych może być mylące. Jeśli porównasz niestandardową klasę bez zdefiniowanej __eq__metody, dwa obiekty będą równe tylko wtedy, gdy będą dokładnie tym samym obiektem:
Zatem wartości atrybutów nie mają znaczenia. Ale za pomocą klasy danych i eq=True(ustawionej domyślnie) dodawana jest bardziej oczekiwana forma równości, w której porównywane są atrybuty (tj. __eq__jest zastępowana):
Zamówienie
Ustawiając orderparametr na true (domyślnie false) i eq true ( other=Truei eq=Falsespowoduje to wyrzucenie błędu), metody:
__lt__()__le__()__gt__()__ge__()
Niezmienność i mieszanie
Na koniec porozmawiajmy o argumentach frozeni unsafe_hash. Argumenty te są bardzo przydatne i ułatwiają prawidłowe zarządzanie mieszaniem, równością i mutacjami. Jeśli nie jesteś zaznajomiony z haszowaniem w Pythonie, polecam przeczytanie artykułu: Understanding Hashing and Equality in Python with __hash__ and __eq__ .
Ustawienie frozen=Trueokreśla, że klasa powinna być tylko do odczytu lub niezmienna, tj. po zainicjowaniu obiektu nie można zmienić żadnych pól:
Te dwie właściwości frozeni eqwpłyną na utworzoną niejawną metodę mieszania:
frozen=True, eq=True=>__hash__-metoda jest generowana automatycznie przy użyciu pólfrozen=True, eq=False=> domyślna__hash__-metoda, tzn. nieużywanie pólfrozen=False, eq=True=> Unhashable, błąd jest zgłaszany, jeśli jest hashowanyfrozen=False, eq=False=> domyślna__hash__-metoda, tzn. nieużywanie pól
Ale dlaczego klasa musi być zamrożona? Jeśli dodasz obiekt do zestawu lub słownika, wygenerowany skrót jest używany do umieszczenia go w mapie skrótów. Później, gdy chcesz odzyskać obiekt, użyj tego samego skrótu, aby go znaleźć. Teraz, jeśli obiekt został zmieniony, hash również powinien się zmienić (ponieważ jest oparty na polach). W rezultacie nie będziesz mógł ponownie znaleźć obiektu. Tak więc, aby hash pozostał stały, pola, na których jest oparty, muszą pozostać stałe. Z tego powodu if eq=Truei frozen=False, nie ma dostępnej metody mieszania.
co z unsafe_hash? Jak opisano, predefiniowane zachowanie niejawnej definicji __hash__opiera się na zasadach promujących najlepsze praktyki. Jednakże, jeśli mimo to nadal chcesz mieć __hash__zdefiniowaną metodę, być może ze względu na szczególne okoliczności, możesz unsafe_hash=Trueją ustawić i tak się stanie. Należy jednak pamiętać, że niebezpieczne słowo kluczowe pojawia się nie bez powodu:
Wniosek
@dataclass w Pythonie to przydatny dekorator, który pozwala zaoszczędzić czas, postępować zgodnie z najlepszymi praktykami i uprościć proces tworzenia klas. Uważam, że nadaje się do wielu różnych sytuacji.
Dziękuje za przeczytanie!
Możesz być zainteresowanym także tym:

![Czym w ogóle jest lista połączona? [Część 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































