pyYAML错误“!”在一个字符串中

时间:2012-11-08 01:10:51

标签: python yaml pyyaml

首先,免责声明:我对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文件不是一个选项。必须使用解析器在代码中修复问题。

3 个答案:

答案 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)。