class human(object): def __init__(self, name=''): self.name = name @property def name(self): return self._name @name.setter def name(self, value): self._name = value class superhuman(human): @property def name(self): return 'super ' + name s = superhuman('john') print s.name # Doesn't work :( "AttributeError: can't set attribute" s.name = 'jack' print s.name
I want to be able to override the property but be able to use the super parent's setter without having to override the setter in the child class.
Is that pythonicaly possible?
You don't need any getters, setters methods to access or change the attributes. You can access it directly using the name of the attributes.
Getters and setters are used to protect your data, particularly when creating classes. For each instance variable, a getter method returns its value while a setter method sets or updates its value. Given this, getters and setters are also known as accessors and mutators, respectively.
The @Getter annotation is used to generate the default getter implementation for fields that are annotated with the annotation. This annotation can also be used at the class level in which Lombok will generate the getter methods for all fields. The default implementation is to return the field as it is.
The constructors are used to initialize the instance variable of a class or, create objects. The setter/getter methods are used to assign/change and retrieve values of the instance variables of a class.
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.
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