I want to create a structure with a messenger class which is shared between several other classes. I want to keep parameters synchronized between the messenger and the sub-classes, and I also want the sub-classes to be able to access each other via the messenger. I have currently implemented it as follows, but am having some issues with synchronization:
class MessengerWrapper:
def __getattribute__(self,attr):
#Force use of custom getattr
return self.__getattr__(self,attr)
def __getattr__(self,attr):
#return the messenger if asking for it
if attr == '_messenger':
return object.__getattribute__(self,attr)
#Return the value of the _messenger instance if its there.
elif hasattr(self._messenger,attr):
return getattr(self._messenger,attr)
#Otherwise return the instances own value
else:
if attr in self.__dict__:
val = object.__getattribute__(self,attr)
#keep the messenger synchronized
setattr(self._messenger,attr,val)
return val
else:
raise AttributeError()
def __setattr__(self,attr,val):
#set the messenger if necessary
if attr == '_messenger':
self.__dict__[attr] = val
#otherwise, set the attribute and sync the messenger
else:
setattr(self._messenger,attr,val)
self.__dict__[attr] = val
class Messenger:
def __init__(self):
self.param1 = 1
class SubClassA(MessengerWrapper):
def __init__(self,messenger):
self._messenger = messenger
self.paramA = 2
class SubClassB(MessengerWrapper):
def __init__(self,messenger):
self._messenger = messenger
self.paramB = 3
def function(self):
total = self.param1 + self.paramB + self.subA.paramA
self.paramA = total
messenger = Messenger()
A = SubClassA(messenger)
B = SubClassB(messenger)
messenger.subA = A
messenger.subB = B
B.function()
print messenger.paramA, B.paramA
#-> 6, 6 (as expected)
print A._messenger.paramA, A.paramA
#-> 6, 2 (I would expect 6, 6 since A.paramA should return A._messenger.paramA)
I am guessing that this discrepancy results from a lack of understanding of when things are stored by reference vs. by value in Python, or maybe some weird loophole in the getattr override. Maybe I could add some sort of synchronization function to ensure that everything stays synced up, but it already feels pretty hackish and I would think that there is a cleaner solution. The end goal is to have a messenger class and sub-classes which interact transparently with that messenger to create/store attributes and keep everything synchronized.
Note that although this example does not show it, the actual application also requires that the sub-classes have access to each other's methods (as well as the messenger's methods). Not sure if this makes any difference or not.
Any ideas? Am I on the right track or should I do something totally different? I looked into metaclasses and decorators, but couldn't immediately see if/how they would help me.