I have a SuperClass which defines a property and it's setter, like so:
class A(object):
def __init__(self):
self._mode = None
@property
def mode(self):
# to be overriden in subclass to implement the actual getter code
raise NotImplementedError
@mode.setter
def mode(self, value):
# common assertions and input validations
self._set_mode(value)
def _set_mode(self, value):
# to be overriden in subclass to implement the actual setter code
raise NotImplementedError
class B(A):
@property
def mode(self):
return self._mode
def _set_mode(self, value):
self._mode = value
obj = B()
obj.mode = 'test'
Which raises
obj.mode = 'test'
AttributeError: can't set attribute
It would seem that I have to register a setter in B. I'd usually do this like @A.mode.setter
, but that doesn't quite apply here as I don't actually want to define a new setter in B, just re-use the one from A.
Does anyone have a hint on how to solve this? Might be trivial, but I'm not seeing it right now :/
Python's property() is the Pythonic way to avoid formal getter and setter methods in your code. This function allows you to turn class attributes into properties or managed attributes. Since property() is a built-in function, you can use it without importing anything.
Do the setter/getter methods always affect only values in objects where they are declared, even called from a subclass by inheritance? You cannot inherit the methods but not the variables. You inherit everything from the parent class. Private just means that you cannot directly access it, but it is still there.
Python property() function returns the object of the property class and it is used to create property of a class. Syntax: property(fget, fset, fdel, doc) Parameters: fget() – used to get the value of attribute. fset() – used to set the value of attribute.
Accessor properties are represented by “getter” and “setter” methods. In an object literal they are denoted by get and set : let obj = { get propName() { // getter, the code executed on getting obj. propName }, set propName(value) { // setter, the code executed on setting obj.
the getter and setter are stored as attributes of the property
object (respectively as .fget
and .fset
), so as soon as you overload the property in a child class you most explicitely provide both getter and setters, ie:
class B(A):
@property
def mode(self):
return self._mode
@mode.setter
def mode(self, value):
self._mode = value
So if you want to make the getter and/or setter overloadable without having to redeclare the property, you have to define a _get_mode
method and make your property's getter delegate to this method, just like you did for the setter.
class A(object):
def __init__(self):
self._mode = None
@property
def mode(self):
return self._get_mode()
def _get_mode(self):
# to be overriden in subclass to implement the actual getter code
raise NotImplementedError
@mode.setter
def mode(self, value):
# common assertions and input validations
self._set_mode(value)
def _set_mode(self, value):
# to be overriden in subclass to implement the actual setter code
raise NotImplementedError
class B(A):
def _get_mode(self):
return self._mode
def _set_mode(self, value):
self._mode = value
Analogously with using mode.setter
inside A
’s definition, this answer to a related question suggests to use a property of a base class to define a property on a subclass like so:
class B(A):
@A.mode.getter # only this line is changed!
def mode(self):
return self._mode
def _set_mode(self, value):
self._mode = value
Here, mode.setter
will be the same as it was for A
, but we’ve replaced the getter.
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