bootleg
bootleg

Reputation: 187

Override both getter and setter of a property

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

Answers (1)

Sebastian Loehner
Sebastian Loehner

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

Related Questions