2

If I define a property (with @property) in a base class, how can I override the setter of this property in a subclass ?

more specifically:

if I create a class A:

class A(object):
   def __init__(self, val):
       self._val = val

   @property
   def val(self):
       return self._val

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

and create a sub-class B of A

class B(A):
    def __init__(self, val):
        super(B, self).__init__(val)

how can I prevent the setter from being called on B ?

Is there any way to write the equivalent of:

class B(A)
    def __init__(self, val):
        super(B, self).__init__(val)

    @val.setter
    def val(self, value):
        raise ValueError("cannot set value on B")

Actually, the code above would raise a:

NameError: name 'val' is not defined

Is it necessary to re-define thre getter in B for this to work?

If I write:

class B(A):
    def __init__(self, val):
        super(B, self).__init__(val)

    @property
    def val(self):
        return self._val

     @val.setter
     def val(self, value):
         raise AttributeError("cannot set val of B")

all works fine... Is there any work-around?

mgilson
  • 300,191
  • 65
  • 633
  • 696
  • As the answer to the duplicate describes, there is technically no way to do what you ask (that is, "prevent the setter from being called on B"), because a property is a single object with the getter and setter wrapped inside it, so you can't change the setter without changing the whole property. However, you can achieve the same effect by using `@superclass.prop.setter`, which will create a new property with the same getter but a different setter. Your new setter will indeed be called on B, but it can then block setting the value if that's what it wants to do. – BrenBarn Sep 17 '14 at 21:43

0 Answers0