Im folgenden finden Sie ein weiteres Beispiel dafür, wie @property
helfen kann, wenn Code refakturiert werden muss, das von hier stammt (ich fasse es nur kurz zusammen):
Stellen Sie sich vor, Sie haben eine Klasse Money
wie diese erstellt:
class Money:
def __init__(self, dollars, cents):
self.dollars = dollars
self.cents = cents
und ein Benutzer erstellt eine Bibliothek, die von dieser Klasse abhängt, in der er/sie z.B. verwendet
money = Money(27, 12)
print("Ich habe {} Dollar und {} Cent.".format(money.dollars, money.cents))
# gibt aus Ich habe 27 Dollar und 12 Cent.
Nehmen wir nun an, Sie entscheiden sich dazu, Ihre Money
-Klasse zu ändern und die Attribute dollars
und cents
loszuwerden, sondern entscheiden stattdessen, nur die Gesamtmenge an Cents zu verfolgen:
class Money:
def __init__(self, dollars, cents):
self.total_cents = dollars * 100 + cents
Wenn der oben erwähnte Benutzer nun versucht, seine/ihre Bibliothek wie zuvor auszuführen
money = Money(27, 12)
print("Ich habe {} Dollar und {} Cent.".format(money.dollars, money.cents))
es wird zu einem Fehler führen
AttributeError: 'Money' object hat kein Attribut 'dollars'
Das bedeutet, dass nun jeder, der sich auf Ihre ursprüngliche Money
-Klasse verlässt, alle Codezeilen ändern müsste, in denen dollars
und cents
verwendet werden, was sehr schmerzhaft sein kann... Also, wie könnte dies vermieden werden? Durch Verwendung von @property
!
So funktioniert es:
class Money:
def __init__(self, dollars, cents):
self.total_cents = dollars * 100 + cents
# Getter und Setter für Dollar...
@property
def dollars(self):
return self.total_cents // 100
@dollars.setter
def dollars(self, new_dollars):
self.total_cents = 100 * new_dollars + self.cents
# Und der Getter und Setter für Cents.
@property
def cents(self):
return self.total_cents % 100
@cents.setter
def cents(self, new_cents):
self.total_cents = 100 * self.dollars + new_cents
wenn wir jetzt aus unserer Bibliothek aufrufen
money = Money(27, 12)
print("Ich habe {} Dollar und {} Cent.".format(money.dollars, money.cents))
# gibt aus Ich habe 27 Dollar und 12 Cent.
wird es wie erwartet funktionieren und wir mussten keinen einzigen Code in unserer Bibliothek ändern! Tatsächlich müssten wir nicht einmal wissen, dass sich die von uns abhängige Bibliothek geändert hat.
Auch der setter
funktioniert gut:
money.dollars += 2
print("Ich habe {} Dollar und {} Cent.".format(money.dollars, money.cents))
# gibt aus Ich habe 29 Dollar und 12 Cent.
money.cents += 10
print("Ich habe {} Dollar und {} Cent.".format(money.dollars, money.cents))
# gibt aus Ich habe 29 Dollar und 22 Cent.
Sie können @property
auch in abstrakten Klassen verwenden; ich gebe ein minimales Beispiel hier.