Your actual problem is, that you want a behaviour similar to a call by reference in C++. To achieve this, what you could do is to work with a little hack to emulate a memory location. Found here The reason for that to work is found in this questions accepted answer, it is related to Pythons mutable and immutable objects.
class ref:
def __init__(self, obj): self.obj = obj
def get(self): return self.obj
def set(self, obj): self.obj = obj
class B:
def __init__(self, msg):
self.msg = msg
class A:
def __init__(self, msg):
self.msg = ref(msg)
self.b = B(self.msg)
def update(self, msg):
self.msg.set(msg)
a = A('hello')
print a.msg.get() #hello
print a.b.msg.get() #hello
a.update('bye')
print a.msg.get() #bye
print a.b.msg.get() #bye
If however this means too many changes to your code, what you could also do is to define a method msg(self)
in every function with a msg
, renaming msg
to message
or whatever.
That way you would get the String by calling a.msg()
for example, which would represent less change to your existing code. But I fear that there is no way of solving your problem without any change to your code.
Sample two, with a msg()
method:
class B:
def __init__(self, msg):
self.message = msg
def msg(self):
return self.message.get()
class A:
def __init__(self, msg):
self.message = ref(msg)
self.b = B(self.message)
def update(self, msg):
self.message.set(msg)
def msg(self):
return self.message.get()
a = A('hello')
print a.msg() #hello
print a.b.msg() #hello
A third solution I see would be to use a List
instead of a reference class:
class B:
def __init__(self, msg):
self.msg = msg
class A:
def __init__(self, msg):
self.msg = [msg]
self.b = B(self.msg)
def update(self, msg):
self.msg[0] = msg
a = A('hello')
print a.msg[0] #hello
print a.b.msg[0] #hello
a.update('bye')
print a.msg[0] #bye
print a.b.msg[0] #bye
In general you could use any other mutable object for this purpose, but take care of being aware that you can not reassign the mutable Object in some "child Class" like B
is in your example.