我正在尝试创建一个yaml格式,允许我在另一个对象中创建一个对象。 在此示例中,我尝试创建一个State Machine对象,同时在它们之间填充一些状态和连接。
yaml.load("""
!statemachine {
states: [
!state { name: p1 },
!state { name: p2 },
!state { name: p3 },],
connections:
[!connection { 'pim' : [p1,p2]}]}
""")
!statemachine有一个构造函数,用于生成MyStateMachine
类型的对象!state有一个构造函数,它生成一个MyState类型的对象
!connection有一个构造函数,它应该使用名称为p1的对象生成并添加一个连接
我有两个问题:
1 - 在创建 statemachine 并且其中没有状态后调用 state 的构造函数
2 - 检索对象p1并在其上调用方法add_connection。
提前致谢
答案 0 :(得分:6)
让我们尝试对象的真pyyaml语法
myyaml.py:
import yaml,sys
class StateMachine(object):
pass
class State(object):
pass
class Connection(object):
pass
if __name__ == '__main__':
o = yaml.load("""
!!python/object:myyaml.StateMachine {
states: [
!!python/object:myyaml.State { name: p1 },
!!python/object:myyaml.State { name: p2 },
!!python/object:myyaml.State { name: p3 },],
connections:
[ !!python/object:myyaml.Connection { 'pim' : [p1,p2]}]}
""")
print o.states[0].name
print o.states[1].name
print o.connections[0].pim
sys.exit(0)
获取:
p1
p2
['p1', 'p2']
永远不要在模块的根块中尝试yaml.load(),始终使用if __name__ == '__main__'
或在确保调用一次的函数中调用它。
请注意yaml声明:
!!python/object:myyaml.State { name: p1 },
此时yaml尝试再次导入myyaml.py,在另一个上下文中,并且将执行模块根目录中的所有代码,如果你将yaml.load或类似的东西放在模块的根目录中,你可能会遇到无限循环或意外结果。
答案 1 :(得分:0)
要补充pylover's answer:如果在某个时候您需要对序列化/反序列化过程进行更多控制,请尝试yamlable。我为我们的一些生产代码编写了此程序包,以便对yaml到对象的绑定获得更多控制。
在您的示例中:
import yaml
import sys
from yamlable import YamlAble, yaml_info
@yaml_info(yaml_tag_ns='myyaml')
class StateMachine(YamlAble):
def __init__(self, states, connections):
self.states = states
self.connections = connections
# def to_yaml_dict(self):
# return vars(self)
#
# @classmethod
# def from_yaml_dict(cls, dct, yaml_tag):
# return StateMachine(**dct)
@yaml_info(yaml_tag_ns='myyaml')
class State(YamlAble):
def __init__(self, name):
self.name = name
# def to_yaml_dict(self):
# return vars(self)
#
# @classmethod
# def from_yaml_dict(cls, dct, yaml_tag):
# return State(**dct)
@yaml_info(yaml_tag_ns='myyaml')
class Connection(YamlAble):
def __init__(self, pim):
self.pim = pim
# def to_yaml_dict(self):
# return vars(self)
#
# @classmethod
# def from_yaml_dict(cls, dct, yaml_tag):
# return Connection(**dct)
if __name__ == '__main__':
o = yaml.safe_load("""
!yamlable/myyaml.StateMachine {
states: [
!yamlable/myyaml.State { name: p1 },
!yamlable/myyaml.State { name: p2 },
!yamlable/myyaml.State { name: p3 },],
connections:
[ !yamlable/myyaml.Connection { 'pim' : [p1,p2]}]}
""")
print(o.states[0].name)
print(o.states[1].name)
print(o.connections[0].pim)
print(yaml.safe_dump(o))
# Note: these also work
# print(o.loads_yaml(""" ... """))
# print(o.dumps_yaml())
sys.exit(0)
如果您需要更改默认行为,例如仅转储某些字段,或更改其结构以进行转储,或在加载时执行一些自定义实例创建,请取消注释相应的方法。
有关更多详细信息,请参见yamlable documentation