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