1

Using Python 3, I want to overload a property setter (add instructions) in a child class. The following code seems right, but running it will raise an AttributeError: 'super' object has no attribute 'value'.

class Base(object):
    def __init__(self):
        self._value = 0

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        self._value = val


class Child(Base):
    def __init__(self):
        super().__init__()
        self._double = 0

    @property
    def value(self):
        # I don't want to rewrite the getter so I call super
        return super().value

    @value.setter
    def value(self, val):
        # Get in trouble here
        super().value = val
        self._double = val * 2


c = Child()
c.value  # prints 0
c.value = 1  # raises error

I can't use self.value = val in the overloaded setter because it will cause a RecursionError.

What am I doing wrong?

Edit: I don't think this question is a duplicate of the mentioned one. My question really is: "Can I override a setter in a child class and call the parent one without rewriting the same assignment?"

This is why I'm trying to do super().value = val instead of self._value = val.

Why is return super().value working, and super().value = val isn't?

Answer

(Since it's marked as duplicate I can't post an answer so here it is:)

Got the answer here: How to call a property of the base class if this property is being overwritten in the derived class?.

In short: use Base.value.fset(self, val) instead of super().value = val.

class Child(Base):
    def __init__(self):
        super().__init__()
        self._double = 0

    @Base.value.setter
    def value(self, val):
        Base.value.fset(self, val)
        self._double = val * 2
pawamoy
  • 3,382
  • 1
  • 26
  • 44
  • What does it mean to "surcharge" a setter? – Scott Hunter May 24 '17 at 17:16
  • Oh maybe this is not the right word in english. I mean calling the base method PLUS adding some instructions. – pawamoy May 24 '17 at 17:18
  • But `value` is not a method, it's a property, and you cannot call a property. You have to redesign your classes and move code to methods to call them. – phd May 24 '17 at 17:32
  • I'm not trying to call the property (like `super().value()`) if this is what you mean. – pawamoy May 24 '17 at 17:36
  • Got the answer here: https://stackoverflow.com/questions/1021464/how-to-call-a-property-of-the-base-class-if-this-property-is-being-overwritten-i. Wrong duplicate mention. Use `Base.value.fset(self, val)` instead of `super().value = val`. – pawamoy May 25 '17 at 22:49

0 Answers0