[英]Serialize YAML with references in Python and ruamel.yaml
我有一個帶有引用的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")
您的YAML有兩個問題:
1)您應該適當縮進所有內容:第18行和第19行需要縮進更多的兩個空格,以便該序列算作鍵Signals
值;而出於相同的原因,第25-27行也需要縮進4個空格。
2)您可以編寫!Signal
&Signal1 , but IMHO it is more clear to write
&Signal1!Signal . The effect is the same: you get an anchor for a "
. The effect is the same: you get an anchor for a "
!Signal type". Ie the type information is "included" in the anchor
. The effect is the same: you get an anchor for a "
type". Ie the type information is "included" in the anchor
type". Ie the type information is "included" in the anchor
Signal1`中,並且不應在別名中重復。
以下input4.yaml
隨程序input4.yaml
加載,沒有錯誤:
# input4.yaml
- &Signal1 !Signal
Name: AO1
Length: 3
- !Signal &Signal2
Name: AO2
Length: 4
- !Signal &Signal3
Name: AO3
Length: 4
- !Message
Name: Message1
Value: 122
Signals:
- *Signal1
- *Signal2
- !Message
Name: Message2
Value: 123
Signals:
- *Signal1
- *Signal2
- *Signal3
順便說一句,它是Python,而不是Phyton(我在問題中已經對其進行了兩次更新,您應該查看人們對您的帖子所做的編輯,並向他們學習)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.