Closed matanox closed 3 years ago
In the code above, the use case is a class that takes care of persistence and initializing from a persisted machine/model.
Obviously I'm still learning which relationship works most cleanly out of those mentioned in the initialization patterns section of the docs. Admittedly not yet comfortable with the model v.s. machine dichotomy of concepts, or the rationalization for a machine relating to an object carrying a semantic notion of a "model" for the machine. It's clear to me why a container is needed for hosting functions and attributes, but help will be much appreciated on understanding why the model metaphor is involved in this way.
Hello @matanster,
transitions
considers the state machine to be a 'rule book' which is applied to the stateful model(s). If this is not required, you can omit the model parameter and let the machine itself act as model. For UC where only one model is required this is often sufficient. If you, however, have to manage multiple models, this separation can become quite handy. You can change the rulebook without touching (and even knowing) each individual model.
Considering your pickle question:
transitions.Machine
and all derivatives contain a list of references to their models. So, when you pickle it, you also pickle all the models:
from transitions import Machine
import pickle
class MyClass:
def __init__(self):
self.machine = Machine(model=[self], states=['A', 'B'])
model = MyClass()
dmp = pickle.dumps(model.machine)
loaded = pickle.loads(dmp)
loaded_model = loaded.models[0] # every machine has a `models` attribute with a list of models
assert not loaded_model == model
assert type(loaded_model) == type(model)
The pickled model will of course contain all the decorated methods already. If you want to add a new model as done in your example above (StateObject
is more or less adding a second instance when the file exists), you do it via Machine.add_model
.
This being said I'd ask you to post future questions about how to use transitions
on Stack Overflow.
Your question gains higher visibility since most developers look for help there. The targeted community is larger; Some people will even help you to formulate a good question. People get 'rewarded' with 'reputation' to help you. You also gain reputation in case this questions pops up more frequently. It's a win-win situation. . Tag your question with [python] and [transitions] to make sure, that users of transitions will receive a notification. If the SO community cannot answer you question and I haven't answered in a week, you can notify me by opening a new issue.
Firstly, thanks for this great library!
If I'm correct then I figure the hard way that
machine.add_model()
needs to be called in the following usage pattern where the model is the class encapsulating the machine, and the machine is read back from a pickle:It seems that
add_model()
is necessary after the unpickling, in order that the initialization magic that adds methods to the model class happens.If that's the case, maybe it helps to have this here or in the documentation.