如何在YAML配置文件中存储pytransitions机器

时间:2017-12-09 20:23:45

标签: python yaml transitions

我使用pytranstions库来构建有限状态机。

许多用户将机器的配置存储为YAML文件,如@wtgee@limdauto herehere的回复中所示。

现在我可以看到如何创建一个YAML文件来存储状态和转换。但是,我不确定如何在YAML文件中存储与FSM相关的功能。

有人可以告诉我该怎么做吗?

1 个答案:

答案 0 :(得分:1)

我不知道在YAML / JSON中存储实际模型及其功能的便捷方法。我假设您提到的工作流程只是将函数名称存储在JSON中,如下所示:

{    
  "states": ["A", "B", "C"],
  "initial": "A",
  "transitions": [
    {"trigger": "go", "source": "A", "dest": "B", "after": "func_A"},
    {"trigger": "go", "source": "B", "dest": "C", "after": "func_B"}
  ]
}

或YAML:

--- 
initial: A
states: 
  - A
  - B
  - C
transitions: 
  - 
    after: func_A
    dest: B
    source: A
    trigger: go
  - 
    after: func_B
    dest: C
    source: B
    trigger: go

当您将回调存储为字符串时,将立即评估它们,并触发事件(在本例中为go)。假设我们已将上面的JSON / YAML加载到名为d的Python字典中。当dict键与transitions个关键字相同时,您可以初始化这样的模型:

from transitions import Machine
class Model:

    def func_A(self):
        print("func A")

    def func_B(self):
        print("func B")


model = Model()
m = Machine(model, **d)
model.go()
model.go()

您可以向YAML添加描述字段model,指定要加载的模型类(例如'module.models.TestModel')并使用importlib导入模型定义dynamically 。或者,您可以隐式定义所需的模型(例如,REST端点'/ TestModel'初始化TestModel)。 如果您真的想在YAML中存储模型类定义,可以使用pickle / dill序列化类定义:

d["model"] = pickle.dumps(Model)
SerialisedModel = pickle.loads(d.pop("model"))
model = SerialisedModel()
m = Machine(model, **d)

如果您只想存储当前状态,可以直接序列化Machine实例:

d["machine_object"] = pickle.dumps(m)

这比前一种方法更不透明。 在任何情况下,您都应该避免使用函数引用定义回调,因为这可能会在以后导致问题。也许pickle / dill也可以处理这个问题,但我不会指望它。

Dave Kuhlmann提出了更复杂的解决方案here。他的帖子包括以下方法:a)将FSM导出为JSON(Machine - > JSON),b)从JSON生成Python FSM代码,c)从JSON将FSM注入到类中。所有这一切都应该很容易转移到YAML。