How to call a property of the base class if this property is being overwritten in the derived class? How to call a property of the base class if this property is being overwritten in the derived class? python python

How to call a property of the base class if this property is being overwritten in the derived class?


You might think you could call the base class function which is called by property:

class FooBar(Foo):    @property    def bar(self):        # return the same value        # as in the base class        return Foo.bar(self)

Though this is the most obvious thing to try I think - it does not work because bar is a property, not a callable.

But a property is just an object, with a getter method to find the corresponding attribute:

class FooBar(Foo):    @property    def bar(self):        # return the same value        # as in the base class        return Foo.bar.fget(self)


Super should do the trick:

return super().bar

In Python 2.x you need to use the more verbose syntax:

return super(FooBar, self).bar


There is an alternative using super that does not require to explicitly reference the base class name.

Base class A:

class A(object):    def __init__(self):        self._prop = None    @property    def prop(self):        return self._prop    @prop.setter    def prop(self, value):        self._prop = valueclass B(A):    # we want to extend prop here    pass

In B, accessing the property getter of the parent class A:

As others have already answered, it's:

super(B, self).prop

Or in Python 3:

super().prop

This returns the value returned by the getter of the property, not the getter itself but it's sufficient to extend the getter.

In B, accessing the property setter of the parent class A:

The best recommendation I've seen so far is the following:

A.prop.fset(self, value)

I believe this one is better:

super(B, self.__class__).prop.fset(self, value)

In this example both options are equivalent but using super has the advantage of being independent from the base classes of B. If B were to inherit from a C class also extending the property, you would not have to update B's code.

Full code of B extending A's property:

class B(A):    @property    def prop(self):        value = super(B, self).prop        # do something with / modify value here        return value    @prop.setter    def prop(self, value):        # do something with / modify value here        super(B, self.__class__).prop.fset(self, value)

One caveat:

Unless your property doesn't have a setter, you have to define both the setter and the getter in B even if you only change the behaviour of one of them.