Override property setter of base class in Python 3

Nagy László Zsolt gandalf at shopzeus.com
Sun Sep 11 05:46:16 EDT 2016


Example code:


class A:
    def __init__(self, prop=0):
        self.__prop = prop
    
    @property
    def prop(self):
        return self.__prop
    
    @prop.setter
    def prop(self, value):
        self.__prop = value

class B(A):
    @A.prop.setter
    def prop(self, value):
        print("Setting new value",value)
        super().prop = value


b = B(0)
b.prop=10

Result:

Setting new value 10
Traceback (most recent call last):
  File "test.py", line 22, in <module>
    b.prop=10
  File "test.py", line 18, in prop
    super().prop = value
AttributeError: 'super' object has no attribute 'prop'

This seems to be working:


class B(A):
    @A.prop.setter # MAGIC HERE!
    def prop(self, value):
        print("Setting new value",value)
        A.prop.fset(self, value) # MAGIC HERE!

How can I remove the magic? E.g. referencing the base class name
directly, and using some internal name "fset"?

Also, consider this:


class A:
    def __init__(self, prop=0):
        self.__prop = prop
   
    @property
    def prop(self):
        return self.__prop
   
    @prop.setter
    def prop(self, value):
        self.__prop = value


class B(A):
    @A.prop.setter
    def prop(self, value):
        print("Setting new value in B:",value)
        A.prop.fset(self, value) # How use the MRO here?

class C(A):
    @A.prop.setter
    def prop(self, value):
        print("Setting new value in C:",value)
        A.prop.fset(self, value) # How use the MRO here?

class D(B,C):
    pass


d = D(0)
d.prop=10

Result:

Setting new value in B: 10

What if I want to use the "property setter of the superclass"? E.g. the
one that is the next in the MRO?

Thanks,

    Laszlo







More information about the Python-list mailing list