Samouczek deskryptorów Pythona

Samouczek deskryptorów Pythona
Przydatną technikę pisania kodu ogólnego, który mógłby zostać ponownie wykorzystywany między klasami, są obsługiwane przez deskryptory Pythona lub bardziej znane jako deskryptory. Mogą zabrzmieć blisko pojęcia dziedziczenia, ale nie są. Jest to bezpośrednia technika przechwytywania dostępu do atrybutów o wiążącym charakterze. Deskryptory są podstawową funkcją Pythona, która rządzi dużą ilością czarów, ukrytych pod okładką języka. Jeśli kiedykolwiek czułeś, że deskryptory Pythona z niewielkimi funkcjonalnymi implementacjami są przedmiotem zaawansowanym, wówczas ten samouczek jest najlepszą platformą, która sprawuje, że zrozumiesz tę potężną funkcję.

Metody deskryptora

Aby to wyraźnie stwierdzić, klasa, która implementuje __Dostawać_(), __ustawić()_, Lub __usuwać()_ Funkcja protokołu deskryptora dla obiektu jest klasyfikowana jako „deskryptor”. Aby rządzić parametrami różnych klas, które używają obiektu jako odniesienia, dokonane są deskryptory Pythona. Oto trzy określone metody, które będą używane w deskryptorach:

__Dostawać__(): Kiedy próbujesz wyodrębnić dane, __Dostawać__() Atrybut jest wywoływany i to, co dostarczy, jest to, co zostanie dostarczone kodowi wymagające wartości jednej zmiennej. Jest skategoryzowany jako deskryptor bez DATA i jest tylko czytelny.

__ustawić__(): Funkcja __ustawić__() jest wywoływany w celu dostosowania wartości parametrów i nic nie jest zwracane przez tę funkcję. Jest znany jako deskryptor danych, który jest nie tylko czytelny, ale także pisał.

__usuwać__(): Ilekroć parametr jest usuwany z obiektu, __usuwać__() Funkcja jest wywoływana. Jest znany jako deskryptor danych, który jest nie tylko czytelny, ale także pisał.

Musisz egzekwować protokół deskryptora, jeśli używasz deskryptorów Pythona w skrypcie. Najwyższe znaczące funkcje protokołu to Dostawać() I ustawić() Posiadanie kolejnego podpisu.

__get __ (self, obj, type = brak) -> obiekt
__set __ (self, obj, wartość) -> Brak

samego siebie jest instancją deskryptora.
obj jest instancją obiektu, do którego podłączony jest twój deskryptor.
typ to rodzaj obiektu.

Przykład:

Tutaj zdefiniowaliśmy dwie klasy. W deskryptorze klasy zdefiniowaliśmy metody deskryptora. w Dostawać() Metoda, jaźń jest instancją dla deskryptora „Val”, otrzyma wartość „maniaków” i przechowuje ją. Następnie stworzy ciąg z „dla” dołączonego między dostarczonym atrybutem. deskryptor klasy (obiekt):

def __get __ (self, obj, objtype):
wrócić dla".format (ja.Val, ja.val)

Następnie zwróci wartość do metody set (). Ta funkcja następnie sprawdza wartość, niezależnie od tego, czy jest to ciąg, czy nie. W przypadku, gdy wartość jest ciągiem, zostanie zapisana w atrybucie o nazwie „Val”. Jeśli wartość nie jest ciągiem, rzuci wyjątek.

def __set __ (self, obj, val):
Jeśli isinstance (val, str):
samego siebie.val = val
w przeciwnym razie:
Raise TypeError („Nazwa powinna być ciąg”)

Następnie wartość zostanie wydrukowana jako ciąg „geeksforgeeks”.

klasa GFG (obiekt):
val = deskryptor ()
g = gfg ()
G.val = „Geeks”
Drukuj (g.val)

Kiedy spróbujesz uruchomić ten kod, otrzymasz następujące dane wyjściowe:

Geeksforgeeks

Cel deskryptorów

Opiszmy klasę o nazwie „Home” z trzema cechami, a mianowicie: Loc, obszar i cena. Możesz użyć funkcji __w tym__() Aby zainicjować atrybuty klasy.

Dom klasy:

def __init __ (self, loc, obszar, cena):

Następnie możesz użyć funkcji __str __ (), która może zwrócić wynik trzech atrybutów, które możesz przekazać klasie podczas budowania przedmiotu. Funkcja __str __ () zwróci ciąg.

Po wykonaniu tego kodu wyświetli pozornie poprawne wyjście.

Teraz spróbujmy zmienić cenę domu na wartość ujemną, jak poniżej, i wykonaj kod.

W ogóle nie ma żadnych zmian, z wyjątkiem znaku ujemnego, jak pokazano na wyjściu. Wytrzymać! Coś tu jest, prawda?? Dlaczego cena domu jest negatywna. Python na to pozwala, ponieważ Python jest wszechstronnym środowiskiem programistycznym, które konkretnie nie pozwala na sprawdzenie typu.

Zainicjujmy instrukcję „jeśli” w __w tym__() funkcja, aby podnieść wyjątek, jeśli wartość lub cena jest mniejsza niż zero.

Na razie możesz zauważyć, że działa dobrze, a jeśli cena jest mniejsza niż zero, kod generuje błąd wartości.

Jak możemy zrozumieć, __w tym_() Funkcja jest konstruktorem i jest wywoływana tylko raz, gdy tworzysz obiekt klasy. Dlatego później niestandardowe sprawdzanie typu ulegnie awarii. Python zapewnia deskryptory, które specjalizują się w naprawie wszystkich powyższych obaw. Teraz zacznijmy używać deskryptorów w tym samym przykładzie, aby dobrze to zrozumieć.

Klasa deskryptora ' __w tym_() Funkcja ma zmienną lokalną __ PRICE na 0. Na początku podwójny podkreślenie oznacza, że ​​parametr jest prywatny. Służy do odróżnienia parametru ceny klasy deskryptora od klasy domowej.

__Dostawać__() Metoda zwróci cenę. Instancja atrybutu zawiera H1, który jest instancją deskryptora. Atrybut właściciel odnosi się do nazwy klasy „dom” klasy i zwraca cenę.

Funkcja __ustawić__() ma atrybut instancja który zawiera H1 i wartość do przypisania. Sprawdź służy do potwierdzenia wartości. Jeśli wartość jest liczbą całkowitą, zostanie wydrukowana, w przeciwnym razie kod z wyjątkiem błędu typu. Jeśli wartość jest poniżej zera, wyjątek błędu wartości zostanie wrzucony do kodu.

__usuwać__() Funkcja jest wykonywana, gdy atrybut parametru jest usuwany z obiektu.

Klasa domu pozostaje taka sama, chociaż instancja cena klasy deskryptora () dodaje się. w __w tym_() funkcja, dodaj atrybut ceny do ceny instancji, a wywoła ona __ustawić_() funkcjonować.

Podczas uruchamiania tego kodu daje to błąd wartości, ponieważ cena nigdy nie może wynosić zeru.

Teraz spróbuj wykonać kod o wartości ciągu.

Rzuci wyjątek błędu typu.

Istniejąca wartość instancji jest zastąpiona w tworzeniu nowej instancji, ponieważ deskryptory są powiązane z klasą, a nie instancją. Spójrz na poniżej:

Pierwsza wartość została zastąpiona drugą.

Wniosek

Możemy zrozumieć, dlaczego deskryptory z Pythona stały się tak fascynującym tematem i jakie scenariusze użytkowania możesz je dodać, przechodząc przez ten samouczek.