如何在不定义构造函数的情况下保留标记的同时执行往返yaml

2024-05-19 21:56:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试在不修改注释、锚和标记的情况下格式化YAML代码(基本上采用任意YAML代码并强制特定的缩进和其他格式化约定)。为此,我使用鲁阿迈尔.亚马尔0.15.0和往返特性(几乎就是这个示例的逐字记录https://yaml.readthedocs.io/en/latest/example.html)。你知道吗

一切正常,但dump函数正在尝试解析标记。我似乎找不到任何关于如何在保留标记和不尝试加载它们的情况下实际转储的信息。我宁愿不必为这些标记定义构造函数。有人知道怎么做吗?你知道吗

下面是一个简单的例子:

import sys
import ruamel.yaml

yaml_str = """\
- &predef
  b: 42
- !sometag
  a: "with superfluous quotes"   # and with comment
  b: *predef
  c: |
     literal
     block style
     scalar
"""

yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)

yaml_str2 = """\
# example
name: &hey
  # details
  family: !the_tag Smith   # very common
  given: Alice    # one of the siblings
name2: *hey
"""
data2 = yaml.load(yaml_str2)
yaml.dump(data2, sys.stdout)

奇怪的是,第一个例子有效,第二个却没有!有什么好处?下面是我得到的错误:

- &predef
  b: 42
- !!sometag
  a: "with superfluous quotes"   # and with comment
  b: *predef
  c: |
    literal
    block style
    scalar
Traceback (most recent call last):
  File "format_yaml.py", line 31, in <module>
    data2 = yaml.load(yaml_str2)
  File "/opt/bb/lib/python2.7/site-packages/ruamel/yaml/main.py", line 252, in load
    return constructor.get_single_data()
  File "/opt/bb/lib/python2.7/site-packages/ruamel/yaml/constructor.py", line 102, in get_single_data
    return self.construct_document(node)
  File "/opt/bb/lib/python2.7/site-packages/ruamel/yaml/constructor.py", line 112, in construct_document
    for dummy in generator:
  File "/opt/bb/lib/python2.7/site-packages/ruamel/yaml/constructor.py", line 1279, in construct_yaml_map
    self.construct_mapping(node, data)
  File "/opt/bb/lib/python2.7/site-packages/ruamel/yaml/constructor.py", line 1187, in construct_mapping
    value = self.construct_object(value_node, deep=deep)
  File "/opt/bb/lib/python2.7/site-packages/ruamel/yaml/constructor.py", line 162, in construct_object
    data = next(generator)  # type: ignore
  File "/opt/bb/lib/python2.7/site-packages/ruamel/yaml/constructor.py", line 1359, in construct_undefined
    node.start_mark)
ruamel.yaml.constructor.ConstructorError: could not determine a constructor for the tag '!the_tag'
  in "<byte string>", line 4, column 11:
      family: !the_tag Smith   # very common
              ^ (line: 4)

Tags: theinpyyamldatalibpackagesline
1条回答
网友
1楼 · 发布于 2024-05-19 21:56:15

您应该升级到最新的0.15.X版本,并检查 使用YAML()的正确实例化(没有typ='safe', 然后使用.load().dump()方法:

import sys
import ruamel.yaml


yaml_str = """\
# example
name: &hey
  # details
  family: !the_tag Smith   # very common
  given: Alice    # one of the siblings
name2: *hey
"""


yaml = ruamel.yaml.YAML()
# yaml.indent(mapping=4, sequence=4, offset=2)
yaml.preserve_quotes = True
data = yaml.load(yaml_str)
data['name']['given'] = 'Bob'
yaml.dump(data, sys.stdout)

它给出:

# example
name: &hey
  # details
  family: !the_tag Smith   # very common
  given: Bob      # one of the siblings
name2: *hey

相关问题 更多 >