I’m currently using the @property
decorator to achieve “getters and setters” in a couple of my classes. I wish to be able to inherit these @property
methods in a child class.
I have some Python code (specifically, I’m working in py3k) which looks vaguely like so:
class A: @property def attr(self): try: return self._attr except AttributeError: return '' class B(A): @property def attr(self): return A.attr # The bit that doesn't work. @attr.setter def attr(self, value): self._attr = value if __name__ == '__main__': b = B() print('Before set:', repr(b.attr)) b.attr = 'abc' print(' After set:', repr(b.attr))
I have marked the part that doesn’t work with a comment. I want the base class’ attr getter to be returned. A.attr
returns a property object (which is probably very close to what I need!).
Edit:
After receiving the answer below from Ned I thought up what I think is a more elegant solution to this problem.
class A: @property def attr(self): try: return self._attr except AttributeError: return '' class B(A): @A.attr.setter def attr(self, value): self._attr = value if __name__ == '__main__': b = B() print('Before set:', repr(b.attr)) b.attr = 'abc' print(' After set:', repr(b.attr))
The .setter
decorator expects a property object which we can get using @A.attr
. This means we do not have to declare the property again in the child class.
(This is the difference between working on a problem at the end of the day vs working on it at the beginning of the day!)
They don't inherit private variables. This is simply not accurate. Both methods and variables (fields) have visibility restrictions. The subclass can always access (see) protected and public and may (if in same package) access default scoped.
Inheritance allows us to define a class that inherits all the methods and properties from another class. Parent class is the class being inherited from, also called base class. Child class is the class that inherits from another class, also called derived class.
(Each decorator usage copies and updates the prior property object, so note that you should use the same name for each set, get, and delete function/method.) You should avoid this: def set_property(property,value): def get_property(property):
To override a setter in python 2 I did this:
class A(object): def __init__(self): self._attr = None @property def attr(self): return self._attr @attr.setter def attr(self, value): self._attr = value class B(A): @A.attr.setter def attr(self, value): # Do some crazy stuff with `value` value = value[0:3] A.attr.fset(self, value)
To understand where A.attr.fset
came from see the documentation on the property
class: https://docs.python.org/2/library/functions.html#property
I think you want:
class B(A): @property def attr(self): return super(B, self).attr
You mention wanting to return the parent class's getter, but you need to invoke the getter, not return it.
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