Ich ändere einige meiner Klassen von einer umfangreichen Verwendung von Gettern und Setzern zu einer pythonischeren Verwendung von Eigenschaften.
Aber jetzt stecke ich fest, weil einige meiner vorherigen Getter oder Setter die entsprechende Methode der Basisklasse aufrufen und dann etwas anderes ausführen würden. Aber wie kann dies mit Eigenschaften erreicht werden? Wie rufe ich den Property Getter oder Setter in der übergeordneten Klasse auf?
Nur das Aufrufen des Attributs selbst führt natürlich zu einer unendlichen Rekursion.
class Foo(object):
@property
def bar(self):
return 5
@bar.setter
def bar(self, a):
print a
class FooBar(Foo):
@property
def bar(self):
# return the same value
# as in the base class
return self.bar # --> recursion!
@bar.setter
def bar(self, c):
# perform the same action
# as in the base class
self.bar = c # --> recursion!
# then do something else
print 'something else'
fb = FooBar()
fb.bar = 7
quelle
Foo.bar.fset(self, c)
einen geerbten Setter hinzuziehen? Warum nichtFoo.bar.fset(c)
- ohne das "Selbst" - dachte ich, dies sei implizit vorbei?self
impliziert das get aus der KetteFoo.bar.fset
?foo = Foo()
\foo.bar(c)
ausführen, wird kein Selbst übergeben, aber bar () empfängt es von Python. Ich bin kein Python-Experte, mehr oder weniger auch ein Anfänger. Es ist nur ein Gedanke.self
wird nur implizit übergeben, wenn die Methode für eine Instanz einer Klasse aufgerufen wird. Wenn ich beispielsweise eine KlasseA
mit einer Methode habeb(self, arg)
und eine Instanz erstellec = A()
,c.b(arg)
entspricht der AufrufA.b(c, arg)
Super sollte den Trick machen:
In Python 2.x müssen Sie die ausführlichere Syntax verwenden:
quelle
AttributeError
.Es gibt eine Alternative
super
, bei der der Name der Basisklasse nicht explizit angegeben werden muss.Basisklasse A:
In B Zugriff auf den Property Getter der übergeordneten Klasse A:
Wie andere bereits geantwortet haben, ist es:
Oder in Python 3:
Dies gibt den vom Getter der Eigenschaft zurückgegebenen Wert zurück, nicht den Getter selbst, aber es reicht aus, den Getter zu erweitern.
Zugriff auf den Eigenschaftssetzer der übergeordneten Klasse A in B:
Die beste Empfehlung, die ich bisher gesehen habe, ist die folgende:
Ich glaube, das ist besser:
In diesem Beispiel sind beide Optionen gleichwertig, aber die Verwendung von Super hat den Vorteil, unabhängig von den Basisklassen von zu sein
B
. Wenn SieB
von einerC
Klasse erben würden, die auch die Eigenschaft erweitert, müssten Sie denB
Code nicht aktualisieren .Vollständiger Code von B, der die Eigenschaft von A erweitert:
Eine Einschränkung:
Sofern Ihre Eigenschaft keinen Setter hat, müssen Sie sowohl den Setter als auch den Getter definieren,
B
auch wenn Sie nur das Verhalten eines dieser Setter ändern.quelle
super(B, self.__class__)
genau mit funktioniertsuper(class, class)
? Wo ist es dokumentiert?Versuchen
Obwohl ich nicht sicher bin, ob Python das Aufrufen der Basisklasseneigenschaft unterstützt. Eine Eigenschaft ist eigentlich ein aufrufbares Objekt, das mit der angegebenen Funktion eingerichtet wird und dann diesen Namen in der Klasse ersetzt. Dies könnte leicht bedeuten, dass keine Superfunktion verfügbar ist.
Sie können Ihre Syntax jedoch jederzeit ändern, um die Funktion property () zu verwenden:
quelle
Einige kleine Verbesserungen an Maximes Antwort :
__class__
, um das Schreiben zu vermeidenB
. Beachten Sie, dass diesself.__class__
der Laufzeittyp vonself
ist,__class__
ohneself
jedoch der Name der umschließenden Klassendefinition.super()
ist eine Abkürzung fürsuper(__class__, self)
.__set__
stattfset
. Letzteres ist spezifisch fürproperty
s, Ersteres gilt jedoch für alle eigenschaftsähnlichen Objekte (Deskriptoren).quelle
(es sei denn, ich vermisse etwas in Ihrer Erklärung)
quelle