我有一个yaml
带有引用的文件,并且想要读取该文件并创建对象。内容YAML-File
由“消息”类和“信号”类组成。消息可以包含对选定信号的引用列表。什么是好方法?我目前会使用该from_yaml
方法并解码YAML-line
. 我已经尝试过使用两个类 Signal 和 Message 但似乎解析器需要另一种语法或其他东西。
ruamel.yaml.parser.ParserError:解析“input4.yaml”第 18 行第 6 列中的块集合时在“input4.yaml”第 18 行第 17 列中未找到预期的“-”指示符
什么可能是读取和解码文件的好方法。一种可能是忽略引用,使用“from_yaml”解析失败,然后在第二步中手动将引用放在一起,但也许有更好的方法。
附上yaml-File
# input4.yaml
- !Signal &Signal1
Name: AO1
Length: 3
- !Signal &Signal2
Name: AO2
Length: 4
- !Signal &Signal3
Name: AO3
Length: 4
- !Message
Name: Message1
Value: 122
Signals:
- !Signal *Signal1
- !Signal *Signal2
- !Message
Name: Message2
Value: 123
Signals:
- !Signal *Signal1
- !Signal *Signal2
- !Signal *Signal3
我的 phyton 程序看起来像
import ruamel.yaml
class Signal:
def __init__(self, name=None, Length=None):
self.name = name
self.Length = Length
@classmethod
def from_yaml(cls, constructor, node):
for m in constructor.construct_yaml_map(node):
pass
return cls(m['Name'], m['Length'])
def __repr__(self):
return 'Signal(name={.name}, Length={.Length})'.format(self, self)
class Message:
def __init__(self, name=None, DLC=None, object=None, signals=None):
self.name = name
self.dlc = DLC
self.signals = [] if signals is None else signals
@classmethod
def from_yaml(cls, constructor, node):
for m in constructor.construct_yaml_map(node):
pass
if 'Name' in m:
name = m['Name']
elif 'name' in m:
name = m['name']
else:
name = None
object = m['object'] if 'object' in m else None
if 'DLC' in m:
dlc = m['DLC']
else:
dlc = None
if 'Signals' in m:
signals = m['Signals']
else:
signals = None
return cls(name, dlc, object, signals)
#return cls(name, dlc, object, signals)
def __repr__(self):
return 'Message(name={}, DLC={}, signals{})'.format(
self.name, self.dlc, self.object, '[...]' if self.signals else '[]'
)
yaml = ruamel.yaml.YAML(typ='safe')
yaml.register_class(Message)
yaml.register_class(Signal)
with open('input4.yaml') as fp:
data = yaml.load(fp)
print(len(data))
for m in data:
if isinstance(m, Message):
print("Message: ", m.name)
if Message(m).signals is not None:
for l in m.signals:
if isinstance(l, Signal):
print("Signal: ", l.name)
print("finish")