Reputation: 187
I want to override both getter and setter of a property in a subclass. Consider the following python3 code snippet:
class Base():
@property
def value(self):
return "Base.value"
@value.setter
def value(self, value):
pass
class Child(Base):
@Base.value.getter
def value(self):
return "Child.value"
@Base.value.setter
def value(self, value):
pass
c = Child()
print(c.value)
This program prints Base.value
, meaning that the value
getter is not overridden. However if I remove the value
setter in the Child
class, the program prints Child.value
which means the getter is overridden.
What is wrong with this way of overriding properties? Why does modifying the setter changes the behavior of the getter? And how can I correctly override both getter and setter in the subclass?
Upvotes: 2
Views: 1825
Reputation: 1322
From my observations, I think you are supposed to use the @Base.value.setter (or .getter) decorator if only the setter (or getter) needs to be overwritten.
If you have to override both, just use the usual @property approach.
class Base():
def __init__(self):
self._value = 'Value'
@property
def value(self):
print('Base.Getter')
return f'Base.{self._value}'
@value.setter
def value(self, value):
print('Base.Setter')
self._value = value
class Child(Base):
@property
#@Base.value.getter
def value(self):
print('Child.Getter')
return f'Child.{self._value}'
@value.setter
#@Base.value.setter
def value(self, value):
print('Child.Setter')
self._value = value
b, c = Base(), Child()
print(b.value)
print(c.value)
b.value = 'test.base'
c.value = 'test.child'
print(b.value)
print(c.value)
prints:
Base.Getter
Base.Value
Child.Getter
Child.Value
Base.Setter
Child.Setter
Base.Getter
Base.test.base
Child.Getter
Child.test.child
Upvotes: 1