Use just the .getter
decorator of the original property:
class superhuman(human):
@human.name.getter
def name(self):
return 'super ' + self._name
Note that you have to use the full name to reach the original property descriptor on the parent class.
Demonstration:
>>> class superhuman(human):
... @human.name.getter
... def name(self):
... return 'super ' + self._name
...
>>> s = superhuman('john')
>>> print s.name
super john
>>> s.name = 'jack'
>>> print s.name
super jack
The property
descriptor object is just one object, even though it can have multiple methods associated with it (the getter, setter and deleter). The .getter
, .setter
and .deleter
decorator functions provided by an existing property
descriptor return a copy of the descriptor itself, with that one specific method replaced.
So in your human
base class what happens is that you first create the descriptor with the @property
decorator, then replace that descriptor with one that has both a getter and a setter with the @name.setter
syntax. That works because python decorators replace the original decorated function with the same name, it basically executes name = name.setter(name)
. See How does the @property decorator work? for the details on how that all works.
In your subclass you simply use that trick to create a new copy of the descriptor with just the getter replaced.