使用 ruamel.yaml 修改 YAML 会添加额外的新行

     2023-02-26     285

关键词:

【中文标题】使用 ruamel.yaml 修改 YAML 会添加额外的新行【英文标题】:Modifying YAML using ruamel.yaml adds extra new lines 【发布时间】:2017-06-29 13:40:43 【问题描述】:

我需要为 YAML 文件中的现有键添加一个额外的值。以下是我正在使用的代码。

with open(yaml_in_path, 'r') as f:
    doc, ind, bsi = load_yaml_guess_indent(f, preserve_quotes=True)
doc['phase1'] += ['c']
with open(yaml_out_path, 'w') as f:
    ruamel.yaml.round_trip_dump(doc, f,
                                indent=2, block_seq_indent=bsi)

这是输入和输出。

输入

phase1:
  - a
  # a comment.
  - b

phase2:
  - d

输出

phase1:
  - a
  # a comment.
  - b

  - c
phase2:
  - d

如何摆脱bc 之间的新行? (当phase1 是文件中的唯一键或phase1phase2 之间没有空行时,不会出现此问题。)

【问题讨论】:

【参考方案1】:

这里的问题是空行被认为是一种注释,ruamel.yaml 中的 cmets 通过将它们与序列中的元素或映射中的键相关联来保留。该值存储在名为 ca 的复杂属性中,在列表中,如对象 doc['phase1'],与第二个元素相关联。

您当然可以争辩说它应该与***映射/字典相关联,或者与键 phase1 相关联(作为一些最终的空行评论)或与 phase2 作为一些介绍性的空行评论相关联. 上述三个中的任何一个都是有效的,并且库中目前无法控制空行(或注释)所在的策略。

如果您输入“真实”评论(以# 开头的评论),它phase1 关联作为结束评论,因为策略不同。

这显然需要大修,因为ruamel.yaml 的最初目标是: - 从 YAML 加载一些配置 - 改变一些值 - 将配置保存到 YAML 在这种情况下,不会出现此类附加/插入问题。

因此,只有在扩展库并控制附加(尾随)cmets 和/或空行的位置之前,没有真正的解决方案。

在实施此类控制之前,您可以做的最好的事情可能是:

import sys
import ruamel.yaml

yaml_str = """\
phase1:
  - a
  # a comment.
  - b

phase2:
  - d
"""

def append_move_comment(l, e):
    i = len(l) - 1
    l.append(e)
    x = l.ca.items[i][0]  # the end comment
    if x is None:
        return
    l.ca.items[i][0] = None
    l.ca.items[i+1] = [x, None, None, None]

data = ruamel.yaml.round_trip_load(yaml_str)
append_move_comment(data['phase1'], 'c')
ruamel.yaml.round_trip_dump(data, sys.stdout, indent=4, block_seq_indent=2)

我将 indent 的值更改为 4,这是您输入的值(并得到,因为您将它指定为对于 block_seq_indent 而言很小)。

【讨论】:

谢谢。你能解释一下分配 [x, None, None, None] 而不是 [x] 的原因吗?以及在哪里可以查看 ruamel.yaml 的源代码来理解这个数据结构? 我不确定我是否在所有情况下都正确检查了该列表的长度,您也许可以少花钱,但我不会尝试。这不是故意记录的,因为它可以在未来的版本中更改。 ca 属性是ruamel.yaml.comments.Comment() 的一个实例,xruamel.yaml.tokens.CommentToken()。提示:如果你没有人可以问,请使用print(type(l.ca),'\n', type(x)) ;-)。 嘿@Anthon,我刚刚偶然发现了同样的问题。自从您发布此答案以来,是否有任何更新?现在有可能以更优雅的方式避免这种情况吗?谢谢! @jakubka 不,没有(对不起,一直在忙着搬家和装修,最后是接近但不近,所以不要屏住呼吸)。

在 ruamel.yaml 中保留引号

...l.yaml【发布时间】:2017-06-2423:27:43【问题描述】:我正在使用ruamel.yaml来修改YAML文件。我的要求是为现有密钥添加一个值,保留包括订单在内的所有其他内容。我让它工作了,但看起来其他键/值的引号也在这个过程中被修改了... 查看详情

防止长行被包裹在 ruamel.yaml

...nruamel.yaml【发布时间】:2017-06-2911:17:04【问题描述】:我使用load_yaml_guess_indent(f,preserve_quotes=True)读取YAML文件,然后对其进行修改并将其写回。我注意到当它们被写回时,长线被包裹起来。(在80-85个字符后插入换行符。)是否... 查看详情

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

】如何在Python中使用ruamel.yaml从YAML文件中获取注释?【英文标题】:HowcanIgetcommentsfromaYAMLfileusingruamel.yamlinPython?【发布时间】:2016-11-1004:29:54【问题描述】:我想从使用ruamel.yaml加载的YAML文件中获取注释字符串。projectdocumentation... 查看详情

python之ruamel.yaml模块详解(代码片段)

...写方法基本相同,目前来说可以根据自己的习惯选择使用ruamel.yaml还是PyMYAL进行yaml文件的读写操作。2ruamel.yaml安装前提条件是:确保安装了最新版本的pip和setuptools(>=20.6.8)。2.1setuptools安装pipinstall-Upipsetuptoo... 查看详情

如何使用显式引用转储 YAML?

】如何使用显式引用转储YAML?【英文标题】:HowtodumpYAMLwithexplicitreferences?【发布时间】:2017-01-2420:05:23【问题描述】:递归引用在ruamel.yaml或pyyaml中效果很好:$ruamel.yaml.dump(ruamel.yaml.load(\'&A[*A]\'))\'&id001-*id001\'但是它(显然... 查看详情

python之ruamel.yaml模块详解|ruamel.yaml与pyyaml的区别(代码片段)

...0开头且仅由数字字符组成的字符串作为八进制,需要使用0o[0-7]+(对于八进制,零+小写o+一个或多个八进制字符)指定此类字符串;YAML1.2不再支持sexagesimals,因此字符串标量12:34:56不需要引用࿱... 查看详情

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

】通过ruamel.yaml转储时如何在yaml文件中保留空值【英文标题】:howtokeepnullvalueinyamlfilewhiledumpingthoughruamel.yaml【发布时间】:2017-11-0223:36:07【问题描述】:我有YAML文件site.yaml:Kvm_BLOCK:ip_address:10.X.X.Xproperty:nullserver_type:zone加载然后转... 查看详情

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

】如何配置ruamel.yaml.dump输出?【英文标题】:Howtoconfigureruamel.yaml.dumpoutput?【发布时间】:2017-01-2811:30:24【问题描述】:有了这个数据结构:d=(2,3,4):\'a\':[1,2],\'b\':\'HelloWorld!\',\'c\':\'Voilà!\'我想要这个YAML:%YAML1.2---[2,3,4]:a:-1-2b:Hello... 查看详情

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

】Conda\\\'ImportError:没有名为ruamel.yaml.comments的模块\\\'【英文标题】:Conda\'ImportError:Nomodulenamedruamel.yaml.comments\'Conda\'ImportError:没有名为ruamel.yaml.comments的模块\'【发布时间】:2017-05-1310:22:41【问题描述】:当我用它运行任何命令... 查看详情

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

】pythonruamel.yaml包,如何获取标题注释行?【英文标题】:pythonruamel.yamlpackage,howtogetheadercommentlines?【发布时间】:2022-01-1401:25:59【问题描述】:我想在标题行获取YAML文件cmets,例如#11111111111111111#11111111111111111#22222222222222222#bbbbbbbb... 查看详情

我可以在 ruamel.yaml 的 CommentedMap 中插入一行吗?

】我可以在ruamel.yaml的CommentedMap中插入一行吗?【英文标题】:CanIinsertalineintoruamel.yaml\'sCommentedMap?【发布时间】:2016-08-2611:20:29【问题描述】:我知道这与thisSOquestion有关,但我最担心的是这是否会与保存的cmets等东西混淆。impor... 查看详情

当 ruamel.yaml 从字符串加载 @dataclass 时,不会调用 __post_init__

】当ruamel.yaml从字符串加载@dataclass时,不会调用__post_init__【英文标题】:Whenruamel.yamlloads@dataclassfromstring,__post_init__isnotcalled【发布时间】:2019-01-0221:30:44【问题描述】:假设我创建了一个@dataclassclassFoo,并添加了一个__post_init__... 查看详情

如何在 Python 中向 YAML 文件添加注释

...Python【发布时间】:2015-09-0818:08:15【问题描述】:我正在使用https://pypi.python.org/pypi/ruamel.yaml编写一个YAML文件代码是这样的:importruamel.yamlfromruamel.yaml.commentsimportCommentedSeqd 查看详情

在python中安装yaml(代码片段)

...更新pip并安装setuptools#pythonpipinstall-Upipsetuptoolswheel1.2.安装ruamel.yaml#pythonpipinstallruamel.yaml1.3.安装PyYaml#pythonpipinstallPyYAML2.扩展Pyyaml和ruamel.yaml_mjiansun的博客-CSDN博客_pythonruamel.yaml:https://blog.csdn.net/u013066730/article/details/101052072文章系个... 查看详情

如何使用yaml-cpp修改map节点(删除key的值)

】如何使用yaml-cpp修改map节点(删除key的值)【英文标题】:howtouseyaml-cpptomodifyamapnode(deletekey\'svalue)【发布时间】:2017-10-1007:10:53【问题描述】:以这个yaml节点为例:-flow:-do:?command:-command1:command-command2:command-command3:commandname:namebl... 查看详情

如何在 C 中修改现有的 YAML 节点?

...:我不是C程序员,但最近对它产生了兴趣。我正在尝试使用Clibyaml库修改YAML文件的节点。当我尝试从事件标量数据修改节点时,编译器不会抱怨,但会出现分段错误错误。while(!done)/*Getthenexttoken.*/if(!yaml_parser 查看详情

在保留注释的同时在 java 中修改 YAML

...ML:#ThisisatestYAMLname:abcdage:23#TestYAMLendshere.有没有办法可以使用j 查看详情

可以修改生成的 helm 模板吗?

...plate?【发布时间】:2021-11-0114:58:50【问题描述】:我正在使用静态yaml文件来安装gitlab。所以我跑了helmtemplategitlabgitlab/gitlab-f"config.yaml">gitlab.yaml但是在这个生成的yaml文件中我总是要修改这三个值:apiVersion:v 查看详情