Heim > Artikel > Backend-Entwicklung > Detaillierte Erläuterung der Eigenschaftsverwendung des Python-Dekorators
Der @property-Dekorator kann eine Methode in eine Eigenschaft umwandeln und sie aufrufen. Werfen wir einen Blick auf die Analyse der Verwendungsfähigkeiten des @property-Dekorators.
Was ist der Nutzen von @property? Es scheint, dass auf eine Methode als Attribut zugegriffen wird.
Sie können sehen, dass der Bereich zwar als Methode definiert ist, aber nach dem Hinzufügen von @property , Sie können direkt auf c.area als Eigenschaft zugreifen
class Circle(object): def __init__(self, radius): self.radius = radius @property def area(self): return 3.14 * self.radius ** 2 c = Circle(4) print c.radius print c.areaJetzt tritt das Problem auf, dass jedes Mal, wenn c.area aufgerufen wird, es einmal berechnet wird, was eine Verschwendung von CPU ist einmal? Was? Das ist die Lazy-Eigenschaft.
Wie Sie sehen können, wird „evalute“ nur einmal ausgegeben, und der Mechanismus von @lazy sollte gut verstanden werden.
class lazy(object): def __init__(self, func): self.func = func def __get__(self, instance, cls): val = self.func(instance) setattr(instance, self.func.__name__, val) return val class Circle(object): def __init__(self, radius): self.radius = radius @lazy def area(self): print 'evalute' return 3.14 * self.radius ** 2 c = Circle(4) print c.radius print c.area print c.area print c.areaHier Die Lazy-Klasse weist darauf hin, dass es sich bei der ersten Ausführung von c.area um einen Deskriptor handelt. Wenn dieser nicht gefunden wird, wird er aufgrund von Auftragsproblemen durchsucht Im Klassenraum gibt es die Methode „area( )“, also wird sie von __get__ abgefangen. Rufen Sie in __get__ die Methode „area()“ der Instanz auf und fügen Sie dynamisch eine hinzu Attribut mit demselben Namen zur Instanz und weisen Sie ihr das Ergebnis zu, das heißt, fügen Sie es zu Gehe zu c.__dict__ hinzu.Wenn Sie c.area erneut ausführen, gehen Sie zuerst zu c.__dict__, da es bereits vorhanden ist existiert zu diesem Zeitpunkt, daher werden Sie die Methode „area()“ und __get__ nicht durchlaufen. HinweiseBitte beachten Sie die folgenden Codeszenarien: Codeausschnitt 1 :
Codeausschnitt 2:
Der Unterschied zwischen Code 1 und 2 besteht darin, dassclass Parrot(object): def __init__(self): self._voltage = 100000 @property def voltage(self): """Get the current voltage.""" return self._voltage if __name__ == "__main__": # instance p = Parrot() # similarly invoke "getter" via @property print p.voltage # update, similarly invoke "setter" p.voltage = 12
Klasse Parrot(object):
class Parrot: def __init__(self): self._voltage = 100000 @property def voltage(self): """Get the current voltage.""" return self._voltage if __name__ == "__main__": # instance p = Parrot() # similarly invoke "getter" via @property print p.voltage # update, similarly invoke "setter" p.voltage = 12Führen Sie den Test unter Python2 separat aus Fragment 1: Ein erwarteter Fehler wird angezeigt. Information AttributeError: Attribut kann nicht festgelegt werden Fragment 2: Korrekter VorgangSiehe In der Python2-Dokumentation stellt @property eine schreibgeschützte Eigenschaft bereit. Der obige Code stellt den entsprechenden @length.setter nicht bereit. Es liegt auf der Hand, dass der Snippet-2-Code einen laufenden Fehler auslöst. Im Python2-Dokument können wir Folgendes finden Folgende Informationen: BIF: property([fget[, fset[, fdel[, doc]] ]]) Gibt ein Eigenschaftsattribut für Klassen neuen Stils zurück (Klassen, die von Objekt abgeleitet sind). Es stellt sich heraus, dass unter Python2 der integrierte Typ Objekt nicht die Standardbasisklasse ist, wenn es keine klare Erklärung gibt (Codeausschnitt 2 ), erbt der von uns definierte Parrot (Codeausschnitt 2) kein Objekt und die Objektklasse stellt nur die @property-Funktion bereit, die wir benötigen. Im Dokument finden Sie die folgenden Informationen: Klasse im neuen Stil Jede Klasse, die von Objekt erbt. Dazu gehören alle integrierten Typen wie Liste und Diktat. Nur Klassen im neuen Stil können die neueren, vielseitigen Funktionen von Python wie __slots__, Deskriptoren und Eigenschaften verwenden __getattribute__().Gleichzeitig können wir auch mit der folgenden Methode überprüfen Zurückgegeben von 36f887267d76e0776cc5fd1023a26dbb, 6093e3c6128582bf9e6a58c99d118a2d können wir sehen, dass f5ae6bbdf402bfea04a71faa8c02de77 der Objekttyp ist, den wir benötigen (Python 3.0 verwendet die Objektklasse als Standardbasisklasse, daher wird f5ae6bbdf402bfea04a71faa8c02de77 zurückgegeben)Um die Kompatibilitätsprobleme während der Übergangsphase der Python-Version des Codes zu berücksichtigen, denke ich, dass bei der Definition von Klassendateien das Objekt explizit als gute Angewohnheit definiert werden sollte
class A: pass >>type(A) <type 'classobj'>
class A(object): pass >>type(A) <type 'type'>Schließlich wird der Code wie folgt sein:
Außerdem wurde
@property in 2.6 und 3.0 hinzugefügt, und 2.5 verfügt nicht über diese Funktion.Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Eigenschaftsverwendung des Python-Dekorators. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!