Ich interessiere mich für die Verwendung @property
in Python. Ich habe die Python-Dokumente gelesen und das Beispiel dort ist meiner Meinung nach nur ein Spielzeugcode:
class C(object):
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
Ich weiß nicht, welchen Nutzen ich aus dem Einwickeln des _x
mit dem Immobiliendekorateur gefüllten Objektors ziehen kann. Warum nicht einfach implementieren als:
class C(object):
def __init__(self):
self.x = None
Ich denke, die Eigenschaftsfunktion kann in einigen Situationen nützlich sein. Aber wenn? Könnte mir bitte jemand einige Beispiele aus der Praxis geben?
Vielen Dank.
python
oop
properties
python-decorators
xiao 啸
quelle
quelle
Antworten:
Andere Beispiele wären die Validierung / Filterung der Mengenattribute (die sie in Grenzen halten oder akzeptabel sind) und die verzögerte Bewertung komplexer oder sich schnell ändernder Begriffe.
Komplexe Berechnung hinter einem Attribut versteckt:
Validierung:
quelle
Ein einfacher Anwendungsfall besteht darin, ein schreibgeschütztes Instanzattribut festzulegen, da das Führen eines Variablennamens mit einem Unterstrich
_x
in Python normalerweise bedeutet, dass es privat ist (interne Verwendung), aber manchmal möchten wir das Instanzattribut lesen und nicht schreiben können es so können wirproperty
dafür verwenden:quelle
c._x
, wenn der Benutzer will. Python hat eigentlich keine echten privaten Attribute.Schauen Sie sich diesen Artikel für eine sehr praktische Anwendung an. Kurz gesagt, es wird erklärt, wie Sie in Python normalerweise die explizite Getter / Setter-Methode loswerden können, da Sie sie
property
für eine nahtlose Implementierung verwenden können, wenn Sie sie irgendwann benötigen .quelle
Eine Sache, für die ich es verwendet habe, ist das Zwischenspeichern von langsam nachzuschauenden, aber unveränderlichen Werten, die in einer Datenbank gespeichert sind. Dies verallgemeinert sich auf jede Situation, in der Ihre Attribute eine Berechnung oder eine andere lange Operation erfordern (z. B. Datenbankprüfung, Netzwerkkommunikation), die Sie nur bei Bedarf ausführen möchten.
Dies geschah in einer Web-App, in der für eine bestimmte Seitenansicht möglicherweise nur ein bestimmtes Attribut dieser Art erforderlich ist, die zugrunde liegenden Objekte selbst jedoch möglicherweise mehrere solcher Attribute aufweisen. Eine Initialisierung aller Objekte bei der Erstellung wäre verschwenderisch, und die Eigenschaften ermöglichen es mir, flexibel zu sein Attribute sind faul und welche nicht.
quelle
@cached_property
?Beim Lesen der Antworten und Kommentare scheint das Hauptthema zu sein, dass den Antworten ein einfaches, aber nützliches Beispiel fehlt. Ich habe hier eine sehr einfache aufgenommen, die die einfache Verwendung des
@property
Dekorateurs demonstriert . Es ist eine Klasse, mit der ein Benutzer die Entfernungsmessung mit einer Vielzahl verschiedener Einheiten angeben und abrufen kann, z. B.in_feet
oderin_metres
.Verwendung:
quelle
Eigenschaft ist nur eine Abstraktion um ein Feld, mit der Sie mehr Kontrolle darüber haben, wie ein bestimmtes Feld manipuliert werden kann, und Middleware-Berechnungen durchführen können. Einige der Verwendungszwecke, die in den Sinn kommen, sind Validierung und vorherige Initialisierung sowie Zugriffsbeschränkungen
quelle
Ja, für das ursprünglich veröffentlichte Beispiel funktioniert die Eigenschaft genauso wie eine Instanzvariable 'x'.
Dies ist das Beste an Python-Eigenschaften. Von außen funktionieren sie genau wie Instanzvariablen! Damit können Sie Instanzvariablen von außerhalb der Klasse verwenden.
Dies bedeutet, dass Ihr erstes Beispiel tatsächlich eine Instanzvariable verwenden könnte. Wenn sich die Dinge ändern und Sie sich dann dazu entschließen, Ihre Implementierung zu ändern und eine Eigenschaft nützlich ist, ist die Schnittstelle zur Eigenschaft von Code außerhalb der Klasse immer noch dieselbe. Eine Änderung von einer Instanzvariablen zu einer Eigenschaft hat keine Auswirkungen auf Code außerhalb der Klasse.
In vielen anderen Sprachen und Programmierkursen wird angewiesen, dass ein Programmierer niemals Instanzvariablen verfügbar machen und stattdessen "Getter" und "Setter" für jeden Wert verwenden sollte, auf den von außerhalb der Klasse zugegriffen werden kann, selbst in dem in der Frage angegebenen einfachen Fall.
Code außerhalb der Klasse mit vielen Sprachen (z. B. Java)
Und bei der Implementierung der Klasse gibt es viele 'Getter' und 'Setter', die genau wie Ihr erstes Beispiel funktionieren: Replizieren Sie eine einfache Instanzvariable. Diese Getter und Setter sind erforderlich, da sich der gesamte Code außerhalb der Klasse ändern muss, wenn sich die Klassenimplementierung ändert. Mit Python-Eigenschaften kann Code außerhalb der Klasse jedoch mit Instanzvariablen identisch sein. Code außerhalb der Klasse muss also nicht geändert werden, wenn Sie eine Eigenschaft hinzufügen oder eine einfache Instanzvariable haben. So anders als die meisten objektorientierten Sprachen, für Ihr einfaches Beispiel Sie können das Instanz - Variable anstelle von ‚Getter‘ und ‚Setter‘ , die wirklich nicht benötigt werden, in dem Wissen sicher , dass , wenn Sie eine Immobilie in der Zukunft ändern, wird der Code unter Verwendung von Ihre Klasse muss sich nicht ändern.
Dies bedeutet, dass Sie nur dann Eigenschaften erstellen müssen, wenn ein komplexes Verhalten vorliegt. Für den sehr häufigen einfachen Fall, in dem, wie in der Frage beschrieben, lediglich eine einfache Instanzvariable erforderlich ist, können Sie einfach die Instanzvariable verwenden.
quelle
Ein weiteres nettes Merkmal von Eigenschaften gegenüber der Verwendung von Setzern und Gettern ist, dass Sie weiterhin OP = -Operatoren (z. B. + =, - =, * = usw.) für Ihre Attribute verwenden können, während Validierung, Zugriffskontrolle, Caching usw. beibehalten werden Die Setter und Getter würden liefern.
Wenn Sie beispielsweise die Klasse
Person
mit einem Settersetage(newage)
und einem Getter geschrieben habengetage()
, müssen Sie Folgendes schreiben, um das Alter zu erhöhen:aber wenn Sie
age
eine Eigenschaft gemacht haben, könnten Sie das viel sauberere schreiben:quelle
Die kurze Antwort auf Ihre Frage lautet, dass es in Ihrem Beispiel keinen Nutzen gibt. Sie sollten wahrscheinlich das Formular verwenden, das keine Eigenschaften enthält.
Der Grund, warum Eigenschaften vorhanden sind, besteht darin, dass Sie, wenn sich Ihr Code in Zukunft ändert und Sie plötzlich mehr mit Ihren Daten tun müssen: Werte zwischenspeichern, Zugriff schützen, externe Ressourcen abfragen ... Sie können Ihre Klasse einfach ändern, um Getter hinzuzufügen und Setter für die Daten, ohne die Schnittstelle zu ändern, sodass Sie nicht überall in Ihrem Code finden müssen, wo auf diese Daten zugegriffen wird, und dies auch ändern müssen.
quelle
Was viele zunächst nicht bemerken, ist, dass Sie Ihre eigenen Unterklassen von Eigentum erstellen können. Dies hat sich als sehr nützlich erwiesen, um schreibgeschützte Objektattribute oder Attribute anzuzeigen, die Sie lesen und schreiben, aber nicht entfernen können. Es ist auch eine hervorragende Möglichkeit, Funktionen wie das Verfolgen von Änderungen an Objektfeldern zu verpacken.
quelle
attr = reader('_attr')
Zeile einen Rückruf oder eine Form der Vorprüfung hinzuzufügenattr = if self.__isValid(value): reader('_attr')
. Vorschläge?attr = reader('_attr')
zuattr = accessor('_attr')
. Danke