I'm trying to make a class with 2 or more mutually dependent attributes (e.g. a and a-plus-1). The idea is to be able to initialize an object with one and only one of these 2 attributes and the other is updated simutaneously. Here is a minimal example:
class Duo:
def __init__(self, a=None, ap1=None):
if (a is None) == (ap1 is None):
raise Exception('ERROR: must initialize with either a or ap1.')
elif a:
self.a = a
self.ap1 = self.a + 1
else:
self.ap1 = ap1
self.a = self.ap1 - 1
This works except a and ap1 will not auto-update if one of them is modified. I checked out this anwser which talks about how to dynamically add property to class, and I came up with the following naive solution:
class Duo:
def __init__(self, a=None, ap1=None):
if (a is None) == (ap1 is None):
raise Exception('ERROR: must initialize with either a or ap1.')
elif a:
Duo.a = property(lambda self: a)
Duo.ap1 = property(lambda self: self.a + 1)
else:
Duo.ap1 = property(lambda self: ap1)
Duo.a = property(lambda self: self.ap1 - 1)
if __name__ == '__main__':
duo_1 = Duo(a=1)
print(f'a = {duo_1.a}, a + 1 = {duo_1.ap1}') # This line prints "a = 1, a + 1 = 2"
duo_2 = Duo(ap1=100)
print(f'a = {duo_2.a}, a + 1 = {duo_2.ap1}') # This line prints "a = 99, a + 1 = 100"
print(f'a = {duo_1.a}, a + 1 = {duo_1.ap1}') # This line prints "a = 99, a + 1 = 100" but "a = 1, a + 1 = 2" expected
This doesn't work either since a and ap1 now become class properties and get changed whenever a new instance is created.
Is there a way to make both a and ap1 auto-updating instance properties?