首先,免责声明:我对YAML不太熟悉。我正在尝试将YAML文档解析为关键值对(不要担心我是如何做的。我已经处理好了这一点)
我的文件看起来像是:
world:
people:
name:Suzy
address:chez-bob
然后,有人去改变它。
world:
people:
name:!$uzy
address:chez-bob
我得到了这个解析错误:
yaml.constructor.ConstructorError: could not determine a constructor for the tag '!$uzy'
这甚至意味着什么?我怎么会去解释它!$只有两个字符? 我只想要一个字符串键和值的字典! 此外,编辑yaml文件不是一个选项。必须使用解析器在代码中修复问题。
答案 0 :(得分:13)
感叹号是YAML标记的前缀。解析器必须通过标记名称为它实现构造函数。有一些默认标签,如!!bool
,!!int
等,甚至还有一些特定于Python的标签,例如!!python/tuple
。
您可以为前缀捕获的多个标记定义自己的构造函数甚至构造函数。通过将前缀定义为''
,您可以捕获所有标记并忽略它们。您可以从构造函数返回标记及其值,只需将其全部视为文本。
>>> import yaml
>>> def default_ctor(loader, tag_suffix, node):
... print loader
... print tag_suffix
... print node
... return tag_suffix + ' ' + node.value
...
>>> yaml.add_multi_constructor('', default_ctor)
>>> yaml.load(y)
<yaml.loader.Loader object at 0xb76ce8ec>
!$uzy
ScalarNode(tag=u'!$uzy', value=u'')
{'world': {'people': {'name': '!$uzy', 'address': 'chez-bob'}}}
>>>
答案 1 :(得分:6)
如果值以“!”开头,则必须将值括在单引号或双引号中;否则它被解释为YAML标签。
world:
people:
name: "!$uzy"
address: chez-bob
答案 2 :(得分:1)
这实际上是PyYAML中的一个错误。它将:
中的name:!$uzy
解释为键/值分隔符,但只有在:
后跟空格或前面的标量(name
时才应该这样做)被引用。后续错误是应该在标量中间允许的感叹号被错误地解释为位于标量的开头并因此引入标记。
key people
的值是字符串name:!$uzy address:chez-bob
,并且在其他解析器中正确处理(包括我作为作者的Python包ruamel.yaml
)。