没有保留 cmets,因为您的实例上没有位置 data
把它们。在往返模式下ruamel.yaml 不会创建普通的 Python
来自 YAML 映射/序列的字典/列表,但它们的子类
(CommentedMap/CommentedSeq) 并附加上一个索引的 cmets
这些容器中的元素。同时,dunder 方法如__get__()
允许(大多数)正常使用这些容器来使用和/或修改它们
你的程序,然后转储它们。
ruamel.yaml 子类化字符串、整数、浮点数(并且在某种程度上扩展
booleans) 以保留有关报价、指数、基数、任何
您的 YAML 中可能出现的锚点等。但是如果 cmets 是
附加到一个标量,而不是它是一个值的容器或
元素,将导致对分配新值的注释丢失。那
是如果你有 YAML:
a: 18 # soon to be 55
b: 42
将其加载到data 并执行data['a'] = 55 您的评论将会丢失。它是
不确定是否可以通过制作容器来改善这种行为
更聪明,值得研究,但前提是这样的标量是映射/序列的一部分。
除了None不能被子类化,所以没地方附上
厘米。布尔值也不能被子类化,但要保留锚ruamel.yaml
将布尔值构造为int 的子类,允许正常使用,例如在
if 语句测试真值。 None 的典型用法
但是正在测试身份(使用`... is None`)并且AFAIK无法伪造。
所以.load() 没有办法给你回复有评论的东西
信息。但是您确实使用了YAML() 实例,而IMO 最好
子类,以保留评论信息。它目前存储了一些
有关上次加载文档的信息,例如文档 YAML 版本
指令(如果提供) (%YAML 1.1)
import sys
import ruamel.yaml
yaml_str = """\
# this document is, by default,
# round-tripped to null
"""
class YAML(ruamel.yaml.YAML):
def load(self, stream):
if not hasattr(stream, 'read') and hasattr(stream, 'open'):
# pathlib.Path() instance
data = super().load(stream)
if data is None:
buf = stream.read_text()
elif isinstance(stream, str):
data = super().load(stream)
buf = stream
else: # buffer stream data
buf = stream.read()
data = super().load(buf)
if data is None and buf.strip():
self._empty_commented_doc = buf
return data
def dump(self, data, stream=None, transform=None):
# dump to stream or Path
if not hasattr(self, '_empty_commented_doc'): # the simple case
return super().dump(data, stream=stream, transform=transform)
# doesn't handle transform
if not hasattr(stream, 'read') and hasattr(stream, 'open'):
with stream.open('w') as fp:
fp.write(self._empty_commented_doc)
super().dump(data, stream)
else:
stream.write(self._empty_commented_doc)
if data is not None:
super().dump(data, stream)
yaml = YAML()
# yaml.indent(mapping=4, sequence=4, offset=2)
# yaml.preserve_quotes = True
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)
data = True
print('----------------')
yaml.dump(data, sys.stdout)
给出:
# this document is, by default,
# round-tripped to null
----------------
# this document is, by default,
# round-tripped to null
true
...
上述内容也可以扩展为处理根级别的标量文档,并且
我正在考虑向 ruamel.yaml 添加更完整的实现。