通过 ruamel.yaml 转储时如何在 yaml 文件中保留空值

Posted

技术标签:

【中文标题】通过 ruamel.yaml 转储时如何在 yaml 文件中保留空值【英文标题】:how to keep null value in yaml file while dumping though ruamel.yaml 【发布时间】:2017-11-02 23:36:07 【问题描述】:

我有 YAML 文件 site.yaml:

Kvm_BLOCK:
  ip_address: 10.X.X.X
  property: null
  server_type: zone

加载然后转储:

ruamel.yaml.dump(site_yaml, new_file, Dumper=ruamel.yaml.RoundTripDumper)

变成了

Kvm_BLOCK:
      ip_address: 10.X.X.X
      property: 
      server_type: zone

如何在属性块中保留这个null

【问题讨论】:

【参考方案1】:

YAML 1.2 中的 null 值(构造为 Python 的 None)可以表示为 nullNullNULL~,指定为 here。

Additionally:

具有空内容的节点被解释为它们是具有空值的普通标量。此类节点通常被解析为“空”值。

因此,您的null 值并没有消失,它只是在使用RoundTripDump 时由ruamel.yamlnull 的默认表示不同地表示。如果再次加载该输出,您将再次获得 None 作为键 property 的值


如果您不喜欢这样,您可以更改 all None/null 值的输出:

import sys
import ruamel.yaml


yaml_str = """\
Kvm_BLOCK:
  ip_address: 10.X.X.X
  property: null
  server_type: zone
"""


def my_represent_none(self, data):
    return self.represent_scalar(u'tag:yaml.org,2002:null', u'NULL')

yaml = ruamel.yaml.YAML()
yaml.representer.add_representer(type(None), my_represent_none)

data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)

将转储:

Kvm_BLOCK:
  ip_address: 10.X.X.X
  property: NULL
  server_type: zone

您可以通过在 Python 中创建不同的类(NULLNullnull 等)来获得更细粒度的控制,并为每个类设置不同的表示器(与 string ruamel.yaml.scalarstring.py 中的子类用于以不同方式表示字符串(双引号、单引号、文字块样式标量)。问题是您不能子类化NoneType,因此这不像字符串标量那样容易透明地完成.

【讨论】:

据我了解,此更改将导致None 在所有情况下都被转储为NULL(包括空文档)。有没有办法根据上下文引起这种行为?例如仅适用于映射值。 发射器可以使用这种上下文,尽管可以从表示器访问,但该状态可能不会及时改变。您可能会更安全地覆盖发射器上的方法(例如expect_block_mapping_value()

以上是关于通过 ruamel.yaml 转储时如何在 yaml 文件中保留空值的主要内容,如果未能解决你的问题,请参考以下文章

Python之ruamel.yaml模块详解

如何在 Python 中使用 ruamel.yaml 从 YAML 文件中获取注释?

ruamel.yaml的使用

如何配置 ruamel.yaml.dump 输出?

python ruamel.yaml 包,如何获取标题注释行?

Conda 'ImportError:没有名为 ruamel.yaml.comments 的模块'