首先,免责声明:我对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文件不是一个选项。必须使用解析器在代码中修复问题。
感叹号是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'}}}
>>>
如果值以“!”开头,则必须将值括在单引号或双引号中;否则它被解释为YAML标记。
world:
people:
name: "!$uzy"
address: chez-bob
这实际上是PyYAML中的一个错误。它解释了 :
在 name:!$uzy
作为键/值分隔符,但它只应该这样做 :
后跟一个空格,或者前面的标量(name
)被引用。后续错误是应该在标量中间允许的感叹号被错误地解释为处于标量的开头并因此引入标记。
密钥的值 people
是字符串 name:!$uzy address:chez-bob
并在其他解析器(包括Python包)中正确处理 ruamel.yaml
其中我是作者)。