Python Descriptors Tutorial

Python Descriptors Tutorial
Eine nützliche Technik zum Schreiben generischer Code, der zwischen den Klassen wiederverwendet werden könnte. Sie mögen dem Begriff der Erbschaft nahe klingen, aber sie sind es nicht. Dies ist eine direkte Technik, um den Zugriff auf Attribute mit bindender Natur zu erfassen. Deskriptoren sind eine grundlegende Funktion von Python, die einen Großteil der Zauberei regiert, die unter dem Cover der Sprache versteckt sind. Wenn Sie jemals das Gefühl hatten, dass Python -Deskriptoren mit kleinen funktionalen Implementierungen ein fortschrittliches Thema sind, ist dieses Tutorial die ultimative Plattform, um Sie dieses leistungsstarke Feature zu verstehen.

Deskriptormethoden

Es deutlich zu sagen, eine Klasse, die implementiert __erhalten_(), __Satz()_, oder __löschen()_ Die Funktion eines Deskriptorprotokolls für ein Objekt wird als „Deskriptor“ eingestuft. Um die Parameter verschiedener Klassen zu regieren, die das Objekt als Referenz verwenden, werden Python -Deskriptoren gemacht. Hier sind drei bestimmte Methoden, die in Deskriptoren verwendet werden:

__erhalten__(): Wenn Sie versuchen, die Daten zu extrahieren, die __erhalten__() Das Attribut wird aufgerufen und was auch immer es bietet, was dem Code bereitgestellt wird, der den Wert einer Variablen fordert. Es wird als Nicht-Daten-Deskriptor eingestuft und ist nur lesbar.

__Satz__(): Die Funktion __Satz__() wird aufgerufen, um die Parameterwerte anzupassen, und durch diese Funktion wird Ihnen nichts zurückgegeben. Es ist als Datendeskriptor bekannt, der nicht nur lesbar, sondern auch schriftlich ist.

__löschen__(): Wann immer der Parameter von einem Objekt entfernt wird, die __löschen__() Funktion wird aufgerufen. Es ist als Datendeskriptor bekannt, der nicht nur lesbar, sondern auch schriftlich ist.

Sie müssen das Deskriptorprotokoll nur durchsetzen, wenn Sie Python -Deskriptoren in Ihrem Skript verwenden. Die größten wichtigen Funktionen des Protokolls sind erhalten() Und Satz() die nachfolgende Signatur haben.

__get __ (Selbst, obj, type = keine) -> Objekt
__set __ (Selbst, obj, Wert) -> Keine

selbst ist die Instanz des Deskriptors.
obj ist eine Instanz des Objekts, mit dem Ihr Deskriptor verbunden ist.
Typ ist die Art eines Objekts.

Beispiel:

Hier haben wir zwei Klassen definiert. Im Klassendeskriptor haben wir Deskriptormethoden definiert. Im erhalten() Methode, das Selbst ist die Instanz für den Deskriptor "Val", es erhält einen Wert "Geeks" und speichert es. Dann wird eine Zeichenfolge mit 'für' zwischen dem bereitgestellten Attribut angehängt. Klassendeskriptor (Objekt):

def __get __ (self, obj, objtype):
zurückkehren für".Format (Selbst.Val, Selbst.val)

Es gibt dann den Wert an die set () -Methode zurück. Diese Funktion prüft dann den Wert, unabhängig davon, ob es sich um eine Zeichenfolge handelt oder nicht. Für den Fall, dass der Wert eine Zeichenfolge ist, wird er in ein Attribut namens "Val" gespeichert. Wenn der Wert keine Zeichenfolge ist, wird eine Ausnahme ausgelöst.

def __set __ (self, obj, val):
Wenn is inviert (val, str):
selbst.val = val
anders:
Geben Sie TypeError an („Name sollte String sein“)

Danach wird der Wert als Zeichenfolge 'Geeksforgeeks' gedruckt.

Klasse GFG (Objekt):
val = Descriptor ()
g = gfg ()
G.val = "Geeks"
Druck (g.val)

Wenn Sie versuchen, diesen Code auszuführen, erhalten Sie die folgende Ausgabe:

Geeksforgeeks

Zweck von Deskriptoren

Beschreiben wir eine Klasse namens "Home" mit drei Eigenschaften, nämlich: Loc, Fläche und Preis. Sie können die Funktion verwenden __drin__() Um die Klassenattribute zu initialisieren.

Unterrichtshaus:

Def __init __ (Selbst, loc, Fläche, Preis):

Dann können Sie die Funktion __str __ () verwenden, die das Ergebnis der drei Attribute zurückgeben kann, die Sie beim Erstellen des Elements an die Klasse übergeben könnten. Die Funktion __str __ () gibt die Zeichenfolge zurück.

Wenn Sie diesen Code ausführen, wird die scheinbar korrekte Ausgabe angezeigt.

Versuchen wir nun, den Preis des Hauses wie unten in einen negativen Wert zu ändern und den Code auszuführen.

Es gibt überhaupt keine Änderung, außer dem negativen Vorzeichen, wie im Ausgang gezeigt. Abwarten! Hier ist etwas los, nicht wahr?? Wie kommt es, dass der Preis eines Hauses negativ ist. Python erlaubt es, weil Python eine vielseitige Entwicklungsumgebung ist, die speziell nicht zulässt.

Lassen Sie uns eine "If" -Anweisung in initialisieren __drin__() Funktionen Sie eine Ausnahme an, wenn der Wert oder Preis weniger als Null ist.

Ab sofort können Sie feststellen, dass es eine gute Leistung erbringt. Wenn der Preis weniger als Null ist, generiert der Code einen Wertfehler.

Wie wir vielleicht verstehen, die __drin_() Funktion ist ein Konstruktor und wird nur einmal aufgerufen, wenn Sie ein Klassenobjekt erstellen. Daher würde später ein individuelles Typ-Checking fehlschlagen. Python bietet Deskriptoren, die sich darauf spezialisiert haben, alle oben genannten Bedenken zu beheben. Lassen Sie uns nun im gleichen Beispiel Deskriptoren verwenden, um es gut zu verstehen.

Die Deskriptorklasse ' __drin_() Die Funktion hat eine lokale Variable __Price bei 0. Zu Beginn impliziert ein doppelter Unterstrich, dass der Parameter privat ist. Es wird verwendet, um den Parameter des Deskriptorklassenpreises von der Homeclass zu unterscheiden.

Der __erhalten__() Die Methode gibt den Preis zurück. Die Attributinstanz enthält H1, eine Deskriptorinstanz. Der Attributbesitzer bezieht sich auf den Namen der Klasse 'Home' und gibt den Preis zurück.

Die Funktion __Satz__() hat ein Attribut Beispiel Das enthält H1 und einen zugewiesenen Wert. Überprüfung wird verwendet, um den Wert zu bestätigen. Wenn der Wert eine Ganzzahl ist, wird er ausgedruckt, andernfalls der Code mit einem Typ -Fehler -Fehler -Ausnahme. Wenn der Wert unter Null liegt, wird die Wertfehlerausnahme in den Code geworfen.

Der __löschen__() Die Funktion wird ausgeführt, wenn das Parameterattribut aus einem Objekt entfernt wird.

Die Homecass bleibt gleich, obwohl die Instanz Preis der Descriptor () Klasse wird hinzugefügt. Im __drin_() Funktion, fügen Sie das Preisattribut zum Instanzpreis hinzu, und es wird das aufrufen __Satz_() Funktion.

Wenn Sie diesen Code ausführen, erhalten Sie einen Wertfehler, da der Preis niemals Null sein kann.

Versuchen Sie nun, den Code mit einem Zeichenfolgenwert auszuführen.

Es wird eine Typ -Fehlerausnahme ausgelöst.

Der vorhandene Instanzwert wird bei der Bildung einer neuen Instanz überschrieben, da die Deskriptoren mit der Klasse und nicht mit der Instanz zusammenhängen. Schauen Sie sich unten an:

Der erste Wert wurde mit dem zweiten überschrieben.

Abschluss

Wir können verstehen, warum Deskriptoren aus Python zu einem so faszinierenden Thema geworden sind und welche Art von Nutzungsszenarien Sie durch dieses Tutorial hinzufügen können.