I have a program that generates a dictionary of objects that are referring to each other. The data in the objects and the references are read from a csv file. Everytime a reference to a new object is encuntered, a new object is generated. Depending on the some attributes, the objects can have slightly different behaviour. The most logical way to account for the difference in behaviour by using different subclasses for each type of behaviour.
My problems is that when a first reference to an object is encountered in the csv file, the desired subclass is not yet known. Creating a temporary object until the final type is known and copying all attributes to a new object will not work since this invalidates all existing references to the object.
I can solve this in two ways:
class A:
fun(self.x):
pass
fun1(self, x):
print("fun1: ", x)
fun2(self, x):
print("fun2: ", x)
a = A()
if <some condition>:
a.fun = fun1
else:
a.fun = fun2
In this case the relation between the class and the behaviour of the instance is lost, which might not be nice when debugging. My other solution is on the one hand more elegant, but feels like bad programming habits:
class A:
pass
class B(A):
def fun(self, x):
print("B: ", x)
class C(A):
def fun(self, x):
print("C: ", x)
a = A()
if <some condition>:
a.__class__ = B
else:
a.__class__ = C
If think most of the objections to assignment to __class__ mentioned in this How dangerous is setting self.__class__ to something else? thread are not valid. Nevertheless, it does not feel good.
I prefer not to include all variants of the method of interest in a single class and call one of these, depending on some data attribute. That would results in objects having methods that are invalid for them.
Does anybody have another, clean, solution?