I have a base class that uses a field:
class Base(object):
def __init__(self, member):
self.member = member
And a derived class that would like to promote this to a property, and add some behaviour:
class Derived(Base):
@property
def member(self):
return super(Derived, self).member
@member.setter
def member(self, value):
print "intercepting setter"
super(Derived, self).member = value
However, this doesn't correctly delegate to the base class:
>>> d = Derived(0)
intercepting setter
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
d = Derived(0)
File "<pyshell#3>", line 3, in __init__
self.member = 2
File "<pyshell#6>", line 9, in member
super(Derived, self).member = value
AttributeError: 'super' object has no attribute 'member'
How should I be doing this?
You're trying to access the super's member
as if it were a class attribute. Try with:
class Derived(Base):
@property
def member(self):
print "intercepting getter"
return self._member
@member.setter
def member(self, value):
print "intercepting setter"
self._member = value
I think that promoting a member to a property is the correct way of doing it. It is like having an int
member in the base and changing it to a method in the derived class. Or like having a normal method and changing it to a static or class method in the inheriter. I guess this just breaks the concept.
You have several options to solve the issue.
I. How about introducing a property of a different (similar) name which then relays all access to the inherited original name? This would be very simple, won't break anything inherited from the base class. But it would also not allow intercepting access to the original member (done in the base class or whereever).
II. Replace the inherited member completely. This just means store the value in a different member and create the property totally from scratch. Later then let it access the store of the original:
class Base(object):
def __init__(self, member):
self.member = member
def baseAccess(self):
return self.member
class Derived(Base):
@property
def member(self):
print "getter",
return self.memberStore
@member.setter
def member(self, value):
print "setter",
self.memberStore = value
b = Base(24)
print "Base(24)"
print "b.member", b.member
print "b.baseAccess()", b.baseAccess()
d = Derived(23)
print "Derived(23)"
print "d.member", d.member
print "d.baseAccess()", d.baseAccess()
b.member = 43
print "b.member = 43"
print "b.member", b.member
print "b.baseAccess()", b.baseAccess()
d.member = 42
print "d.member = 42"
print "d.member", d.member
print "d.baseAccess()", d.baseAccess()
This is the output:
Base(24)
b.member 24
b.baseAccess() 24
setter getter Derived(23)
d.member getter 23
d.baseAccess() getter 23
b.member = 43
b.member 43
b.baseAccess() 43
setter d.member = 42
d.member getter 42
d.baseAccess() getter 42
So all the interceptors are properly taken into account.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With