MultiState#
- class pycraf.utils.MultiState[source]#
Bases:
object
Multi state subclasses are used to manage global items.
MultiState
is a so-called Singleton, which means that no instances can be created. This way, it is guaranteed that only oneMultiState
entity exists. Thus it offers the possibilty to handle a “global” state, because from anywhere in the code, one could query the current state and react to it. One usecase would be to temporarily allow downloading of files, otherwise being forbidden.The
MultiState
class is not useful on its own, but you have to subclass it:>>> from pycraf.utils import MultiState >>> class MyState(MultiState): ... ... # define list of allowed attributes ... _attributes = ('foo', 'bar') ... ... # set default values ... foo = 1 ... bar = "guido"
It is mandatory to provide a tuple of allowed attributes and to create these instance attributes and assign default values. During class creation, this will be validated, for convenience.
After defining the state class, one can do the following:
>>> MyState.foo 1 >>> MyState.set(foo=2) <MultiState MyState> >>> MyState.foo 2
The
set
method returns a context manager,:>>> with MyState.set(foo="dave", bar=10): ... print(MyState.foo, MyState.bar) dave 10 >>> print(MyState.foo, MyState.bar) 2 guido
which makes it possible to temporarily change the state object and go back to the original value, once the
with
scope has ended.Note, that one cannot set the attributes directly (to ensure that the validation method is always run):
>>> MyState.foo = 0 Traceback (most recent call last): ... RuntimeError: Setting attributes directy is not allowed. Use "set" method!
Subclasses will generally override
validate
to convert from any of the acceptable inputs (such as strings) to the appropriate internal objects:class MyState(MultiState): # define list of allowed attributes _attributes = ('foo', 'bar') # set default values foo = 1 bar = "guido" @classmethod def validate(cls, **kwargs): assert isinstance(kwargs['foo'], int) # etc. return kwargs
Notes
This class was adapted from the
ScienceState
class.Methods Summary
hook
(**kwargs)A hook which is called everytime when attributes are about to change.
set
(*[, _do_validate])Set the current science state value.
validate
(**kwargs)Validate the keyword arguments and return the (converted) kwargs dictionary.
Methods Documentation
- classmethod hook(**kwargs)[source]#
A hook which is called everytime when attributes are about to change.
You should override this method if you want to enable pre-processing or monitoring of your attributes. For example, one could use this to react to attribute changes:
>>> from pycraf.utils import MultiState >>> class MyState(MultiState): ... ... _attributes = ('foo', 'bar') ... foo = 1 ... bar = "guido" ... ... @classmethod ... def hook(cls, **kwargs): ... if 'bar' in kwargs: ... if kwargs['bar'] != cls.bar: ... print('{} about to change: {} --> {}'.format( ... 'bar', kwargs['bar'], cls.bar ... )) ... # do stuff ... >>> _ = MyState.set(bar="david") bar about to change: david --> guido >>> _ = MyState.set(bar="david") >>> _ = MyState.set(bar="guido") bar about to change: guido --> david >>> with MyState.set(bar="david"): ... pass bar about to change: david --> guido bar about to change: guido --> david
- classmethod validate(**kwargs)[source]#
Validate the keyword arguments and return the (converted) kwargs dictionary.
You should override this method if you want to enable validation of your attributes.
Notes
One doesn’t need to validate the following things, as it is already take care of by the
MultiState
class:Check that each argument is assigned with a default.
Check that the kwargs keys are in _attributes tuple.