I've created a class and initialized three variables a, b and c. Now I want to call a specific function func1
whenever the variables a or c are changed from the outside, and a function func2
when variable b is changed from the outside.
I am aware that this can be done using decorators, like this:
class Event:
def __init__(self, a, b, c):
self._a = a
self._b = b
self._c = c
@property
def a(self):
return self._a
@a.setter
def a(self, value):
self._a = value
print("Variable a changed!")
self.func1()
@property
def b(self):
return self._b
@b.setter
def b(self, value):
self._b = value
print("Variable b changed!")
self.func2()
@property
def c(self):
return self._c
@c.setter
def c(self, value):
self._c = value
print("Variable c changed!")
self.func1()
def func1(self):
print("Function 1 called")
def func2(self):
print("Function 2 called")
obj = Event(1, 2, 3)
obj.a = 15
obj.b = 10
obj.c = 5
My final code will have 8 or more variables however, and writing a designated @property and @var.setter for every single one of them will be very cumbersome and not really readable.
Is there a simpler way to just say If variables a, c, f, ... are updated, call function X, if b, e, ... are updated, call function Y
?
Thank you!
You could subclass property
with custom features. Here a basic example on how to do that. Notice you should provide a dictionary which maps which property triggers which function (as string).
class TriggerProperty(property):
MAPPER = {'a': 'func1', 'b': 'func2', 'c': 'func1'}
def __set__(self, obj, value):
super().__set__(obj, value)
func_name = self.MAPPER.get(self.fget.__name__)
getattr(obj, func_name)()
class Event:
# ...
@TriggerProperty
def a(self):
return self._a
@a.setter
def a(self, value):
self._a = value
print("Variable a changed!")
# ...