-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Redesign access to variables and their values in Process subclasses #19
Comments
After thinking about option 2, I'm wondering if it shouldn't be better to build this directly on top of A @xsimlab.process(time_dependent=False)
class Foo(object):
coef = xsimlab.variable(())
field = xsimlab.variable((), provided=True)
bar = xsimlab.foreign(Bar, 'bar') What would change:
Like in |
Option 2 (i.e., So properties might still be needed. But instead of defining a property in class Foo(object):
@property
def coef(self):
return self._xsimlab_coef
@coef.setter
def coef(self, value)
self._xsimlab_coef = value Another option (without properties) would be to have some logic which auto-update all external references to a variable each time the latter is updated. |
Using properties, it might be possible to run in the setters all validator or converter functions attached to their respective variables, e.g., class Foo(object):
@property
def coef(self):
return self._xsimlab_coef
@coef.setter
def coef(self, value)
# --- run all `Foo.coef`'s validators here ---
self._xsimlab_coef = value Note on validators: as If we think we don't need to run the validators each time we set a new value (this can be rather done once when creating the inputs, e.g., using the xarray interface), then properties may not be very useful for variables owned by a process and we can use attributes instead. However, properties may still be needed for foreign variables! |
Using properties would also allow some defensive programming. Property setters are indeed not needed for all variables. Read-only properties would prevent setting the value of variables where this is not allowed
At least it is possible to create read-only properties for foreign variables for which EDIT: in some cases we need to be able to update the value of variables that are not inputs nor provided (e.g., main process updating a state variable for which an initial value is provided by another, time-independent process). |
A possible solution to get the value of a foreign variable from an instance of the process class where the original variable is defined: class Foo(object):
def __init___(self):
self._xsimlab_bar_obj = None
@property
def bar(self):
return self._xsimlab_bar_obj.bar where |
A alternative name for foreign variables would be @xsimlab.process(time_dependent=False)
class Foo(object):
coef = xsimlab.variable(())
field = xsimlab.variable((), provided=True)
bar = xsimlab.link(Bar, 'bar') |
Closed in #33 |
Having three different properties (i.e.,
state
,change
,rate
andvalue
as an alias ofstate
) is probably a bad idea:value
(orstate
) is used. In a few cases other properties are used as well, e.g., setting propertychange
in.run_step()
and updatingstate
in.finalize_step()
, but this is less common.Process
subclasses.value
(orstate
).I therefore suggest that a variable only accepts one value. There is different options for implementing this:
We keep the current design, remove all properties mentioned above and instead provide one property, with a short name like
.v
.Maybe it would be possible to get rid of using a specific property to access to the variable value in methods of a
Process
subclass and instead use directly the attribute to access the value, e.g.,Option 2 looks cleaner, actually very much like attrs. It would require a bit of redesign work, though.
Given that we create a model by providing in a dict one or several
Process
subclassesit should be possible to inspect models directly by using the class attributes, e.g.,
The trick to replace the
Variable
object by their value in Process methods (initialize
,run_step
, etc.) would be to create instances of eachProcess
subclasses of the model every time we start a simulation. As processes in a model are ordered in a computationally consistent manner, we can just initialize the subclasses in that order so that we can properly link foreign variables.Overall, option 2 may be actually much cleaner (and possibly more efficient) than the current design.
The text was updated successfully, but these errors were encountered: