import copy class Subject: def __init__(self, excluded): # excluded is a list of attribute names # who should be notified self.__dict__['_observers'] = [] # which attrs should not trigger a notification # obviously it can be done the other way round if needed # i.e.which attrs trigger a notification self.__dict__['_excluded_attrs'] = copy.copy(excluded) def __setattr__(self, attrname, value): # set the attribute self.__dict__[attrname] = value # if the attribute triggers a notification if not attrname in self._excluded_attrs: # notify observers self.notify(attrname, value) def attach(self, observer): if not observer in self._observers: self._observers.append(observer) def detach(self, observer): try: self._observers.remove(observer) except ValueError: pass def notify(self, attrname, value): for observer in self._observers: observer.update(self, attrname, value) # Example usage class Data(Subject): def __init__(self, excluded=[]): # pass up the attrs to be excluded from notification Subject.__init__(self, excluded) class Observer1: def update(self, subject, attrname, value): print 'Observer1: Subject %s has updated attr %s to %s' % (subject.name, attrname, value) class Observer2: def update(self, subject, attrname, value): print 'Observer2: Subject %s has updated attr %s to %s' % (subject.name, attrname, value) # Example def main(): print "Creating data1 without notification for attrs name & surname" data1 = Data(excluded=['name','surname']) print "Creating data2 without notification for attr age" data2 = Data(excluded=['age']) obs1 = Observer1() data1.attach(obs1) data1.attach(obs1) obs2 = Observer2() data2.attach(obs2) data2.attach(obs2) # now try it # you can set any attribute directly print "Setting data1.name=Heather - Notification unnecessary" data1.name = 'Heather' print "Setting data1.num=333 - Notification expected" data1.num = 333; print "Setting data2.name=Molly - Notification expected" data2.name = 'Molly' print "Setting data2.age=28 - Notification unnecessary" data2.age = 28 print "Setting data2.eyecolor=blue - Notification expected" data2.eyecolor='blue'; if __name__ == '__main__': main()