Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to trigger function on value change?

I realise this question has to do with event-handling and i've read about Python event-handler a dispatchers, so either it did not answer my question or i completely missed out the information.

I want method m() of object A to be triggered whenever value v is changing:

For instance (assuming money makes happy):

global_wealth = 0  class Person()     def __init__(self):         self.wealth = 0         global global_wealth         # here is where attribute should be         # bound to changes in 'global_wealth'         self.happiness = bind_to(global_wealth, how_happy)      def how_happy(self, global_wealth):         return self.wealth / global_wealth 

So whenever the global_wealth value is changed, all instances of the class Person should change their happiness value accordingly.

NB: I had to edit the question since the first version seemed to suggest i needed getter and setter methods. Sorry for the confusion.

like image 865
neydroydrec Avatar asked May 31 '11 16:05

neydroydrec


People also ask

What is trigger in Python?

Trigger is a robust network automation toolkit written in Python that was designed for interfacing with network devices and managing network configuration and security policy. It increases the speed and efficiency of managing large-scale networks while reducing the risk of human error.


2 Answers

You need to use the Observer Pattern. In the following code, a person subscribes to receive updates from the global wealth entity. When there is a change to global wealth, this entity then alerts all its subscribers (observers) that a change happened. Person then updates itself.

I make use of properties in this example, but they are not necessary. A small warning: properties work only on new style classes, so the (object) after the class declarations are mandatory for this to work.

class GlobalWealth(object):     def __init__(self):         self._global_wealth = 10.0         self._observers = []      @property     def global_wealth(self):         return self._global_wealth      @global_wealth.setter     def global_wealth(self, value):         self._global_wealth = value         for callback in self._observers:             print('announcing change')             callback(self._global_wealth)      def bind_to(self, callback):         print('bound')         self._observers.append(callback)   class Person(object):     def __init__(self, data):         self.wealth = 1.0         self.data = data         self.data.bind_to(self.update_how_happy)         self.happiness = self.wealth / self.data.global_wealth      def update_how_happy(self, global_wealth):         self.happiness = self.wealth / global_wealth   if __name__ == '__main__':     data = GlobalWealth()     p = Person(data)     print(p.happiness)     data.global_wealth = 1.0     print(p.happiness) 
like image 150
Thiago Chaves Avatar answered Oct 13 '22 04:10

Thiago Chaves


You can use properties if you want to execute code when attributes are changed. Be wary that big side-effects or significant overhead occurring when an attribute is changed is a little bit surprising to anyone using your API, so in some cases you probably want to avoid it by using methods instead.

class A(object):      def m(self, p_value):          print p_value      @property     def p(self):         return self._p       @p.setter     def p(self, value):         self._p = value         self.m(value) 
like image 30
Rosh Oxymoron Avatar answered Oct 13 '22 02:10

Rosh Oxymoron