I have an abstract class A
which has a property for which I need to have a variable listener/setter:
class A(object, metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def someData(self):
pass
# and several other functions which may or may not modify "someData"
The value to the field someData
is being assigned in some of the derived classes. For the other derived classes, the field's value is defined by functions in A
itself which are called by the derived class.
If I try doing something like this, ...
class A(object, metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def someData(self):
pass
@someData.setter
def someData(self, val):
self.someData = val
... the setter is only called when the value of someData
is changing within some function in A
itself. If someData
is assigned a value in one of the derived classes, it does not call the setter function.
How can I implement a setter for an abstract property (I need the setter to be called irrespective of whether the property is being assigned a value in one of the derived classes or in the abstract class)?
Use an alias that subclasses should not override, which calls a setter that subclasses should override:
class A(object, metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def someData(self):
pass
@someData.setter
def _setSomeData(self, val):
self.setSomeData(val)
def setSomeData(self, val):
self._someData = val
Since self.someData
is determined at runtime, not at compile-time, then as long as a subclass only overrides the someData()
method, it will always get used as the 'actual' setter.
Usually when using this pattern, the externally-visible variable name is someData
, but the internal name is _someData
. Because _someData
is not a @property, it can be get and set the normal way, without infinitely recurring. You would then proceed to also make a getter:
@someData.getter
def _getSomeData(self)
return self.getSomeData()
getSomeData(self):
return self._someData
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.