Mad Physicist
Mad Physicist

Reputation: 114320

Use parent property setter when overriding in child class

I have a situation where I am overriding just the setter on a property:

class Parent:
    @property
    def x(self):
        return self.__dict__['x']
    @x.setter
    def x(self, val):
        self.__dict__['x'] = f'P{val}'

class Child(Parent):
    @Parent.x.setter
    def x(self, val):
         super().x = val
         print('all set')

Here, the print statement represents the processing I want to do after invoking the parent's setter. You can just ignore it. super().x = y is my native attempt at invoking said setter. It fails with

Attribute error: 'super' object has no attribute 'x'

What is the correct way to use the property setter from the parent class in the child?

I'd prefer to avoid the following, even though it works just fine, since it involves explicitly calling dunder methods:

Parent.x.__set__(self, val)

As a bonus, is there any way to use super() in the body of the child's setter?

Upvotes: 6

Views: 1913

Answers (2)

John Howroyd
John Howroyd

Reputation: 33

I posted a very similar question.

After a correction to a mistake of mine(by @ShadowRanger) the answer I preferred most was:

class Child(Parent):
    @Parent.x.setter
    def x(self, val):
         super(__class__, type(self)).x.fset(self, val)
         print('all set')

However, I absolutely agree that super().x = val would be a much more natural construct, but would need resolving by the python compiler.

Upvotes: 1

Martin Stone
Martin Stone

Reputation: 13007

You can use the property's fset function:

class Child(Parent):
    @Parent.x.setter
    def x(self, val):
        Parent.x.fset(self, val)
        print('all set')

Upvotes: 4

Related Questions