In my code class A has a property, but class B doesn't inherit it. Does @property support inheritance? Or is it my fault?
class A(object):
def __init__(self):
self._x = 100
@property
def x(self):
return self._x
@x.setter
def x(self, v):
self._x = v
class B(A):
@x.setter
def x(self, v):
self._x = v
The error message is as below:
Traceback (most recent call last):
File "test.py", line 9, in <module>
class B(A):
File "test.py", line 10, in B
@x.setter
NameError: name 'x' is not defined
The NameError is because x isn't in the global scope; it's defined within A's class namespace, so you need to access it there explicitly by using A.x. This is a pretty common mistake, see e.g. python subclass access to class variable of parent.
With properties, though, it can get slightly more complex. If you add a new setter in B, then there is no problem using A.x.setter as shown in Dean's answer. However, if you override an existing setter, you will also alter A's behaviour in doing so. I doubt this is the behaviour that you want.
Instead, in this case, you need to create a new property in the subclass with A's getter and a new setter. I think that this is this easiest way to achieve that, with minimal repetition:
class B(A):
x = property(A.x.__get__) # new property with same getter
@x.setter # new setter on new property
def x(self, v):
...
Note the use of property without the @ syntactic sugar, as I'm not using it to decorate a new method. If you want to access A's setter from B's setter, you can do so with super().x.__set__(whatever).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With