Depending on what exactly you need this for, you might also consider using custom class with a property - all values would be then contained in a single class, not as many objects (in case of many objects, string1=something mistyped instead of string1.value=something breaks your relation because it's not longer the same object).
You can access the property just like a normal member of the class (without parentheses) but its result may be dependent on other values (because behind the scenes, it's still a function).
class Test:
def __init__(self, string1, string2):
self.string1 = string1
self.string2 = string2
@property
def string3(self):
return self.string1 + self.string2
Example of usage:
>>> test = Test("a","b")
>>> print(test.string1, test.string2, test.string3)
a b ab
>>> test.string1 = "c"
>>> print(test.string1, test.string2, test.string3)
c b cb
()call, which makes it clear when exactly data changed and where the changed data came from.