One challenge with some om this classes is the attributes are set dynamically during initialisation. For example, when we create a Species is noes not know about the compartment, but it has a method called vscalar which look as follows
class Species(ObjectInstance):
....
@cached_property
def vscalar(self):
return d.TestFunction(sub(self.compartment.V, 0, True))
One way to make this a bit more explicit it is initialise compartment to a default values (e.g None), and raise some error indicating that the object is not complete, e.g
@dataclass
class Species(ObjectInstance):
compartment: Optional[Compartment] = None
....
@cached_property
def vscalar(self):
if self.compartment is None:
raise RunTimeError("Species is not complete")
return d.TestFunction(sub(self.compartment.V, 0, True))
Ideally, we should rethink how we construct these object and try to avoid to tight coupling between them. Does Species really need to know the compartments, or is it enough that the model has this information?
One challenge with some om this classes is the attributes are set dynamically during initialisation. For example, when we create a
Species
is noes not know about the compartment, but it has a method calledvscalar
which look as followsThis is a problem because an instance of
Species
don't have an attributecompartment
, but this is set dynamically during the model initialisation, see https://github.com/RangamaniLabUCSD/stubs/blob/development/stubs/model.py#L582One way to make this a bit more explicit it is initialise compartment to a default values (e.g
None
), and raise some error indicating that the object is not complete, e.gIdeally, we should rethink how we construct these object and try to avoid to tight coupling between them. Does
Species
really need to know the compartments, or is it enough that the model has this information?We could probably get some inspiration from the Builder pattern https://refactoring.guru/design-patterns/builder which tries to address a similar issue.