What's a good design-pattern / solution for the following problem?
Context: I want to write a Protocol "IVP_Generator" for classes that represent initial value problems. These classes must provide a function solve_ivp that solves the IVP for some time interval. Now, in the by far most common case, one defines a system and uses an off-the-shelve solver. So I want the protocol to look something like this:
class IVP_Generator(Protocol[T]):
"""T some array-type."""
@property
def system(self) -> Callable[[T, T], T]:
"""Represents the vector field f(t, x(t)), if applicable."""
return NotImplemented
def solve_ivp(self, t: T, y0: T) -> T:
"""Return solution y[t] of the IVP."""
if self.system is NotImplemented:
raise NotImplementedError
return default_solver(self.system, t, y0)
Now, I don't really want to make system an @abstractmethod because there are some cases I want to cover where the dynamics are not given by an ODE. In these cases, solve_ivp should be overwritten by the subclass appropriately.
So really the behavior I want is:
- If a subclass does not implement
system, it must implementsolve_ivp - If a subclass implements
systemit can choose to implementsolve_ivpor not.
Is it possible to make @abstractmethod conditional this way? Or should I do something else altogether? I'd rather like to avoid having multiple Protocols.
Aucun commentaire:
Enregistrer un commentaire