首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在不覆盖python的情况下向yaml添加新的键值?

如何在不覆盖python的情况下向yaml添加新的键值?
EN

Stack Overflow用户
提问于 2022-12-03 17:47:54
回答 1查看 27关注 0票数 0

我有一个小python脚本,它负责通过添加新记录来更新yaml文件:

代码语言:javascript
复制
data = yaml.load(file)
data['WIN']['Machine'] = dict(node_labels='+> tfs vs2022')
data['WIN']['Machine'] = dict(vs='vs2022')
yaml.dump(data, file)

每次运行以上脚本时,我都会得到如下所示的更新yaml文件:

代码语言:javascript
复制
WIN:
  Machine:
    vs: vs2022

我想要的输出同时拥有我的键:值对

代码语言:javascript
复制
WIN:
  Machine:
    node_labels: +> tfs vs2022
    vs: vs2022

我想知道为什么行data['WIN'][nodeName] = dict(node_labels='+> tfs vs2022')被下一行覆盖?如何为Machine部分添加几个键:值?

EN

回答 1

Stack Overflow用户

发布于 2022-12-04 08:56:02

这不是与YAML相关的问题,而是与yaml无关的Python代码中的一个概念性问题。

通过将dict作为值分配给键Machine,您可以设置该值的。通过将另一个dict分配给该键,您将完全覆盖该值,擦除前一个键值对。

如果您简化了代码:

代码语言:javascript
复制
data = dict(Machine=None)
data['Machine'] = dict(node_labels='+> tfs vs2022')
print('data 1', data)
data['Machine'] = dict(vs='vs2022')
print('data 2', data)

正如您在第二次赋值之后所看到的,密钥node_labels不再可用。

代码语言:javascript
复制
data 1 {'Machine': {'node_labels': '+> tfs vs2022'}}
data 2 {'Machine': {'vs': 'vs2022'}}

有几种方法可以解决这个问题。您可以在第一个dict中为一个键分配一个值:

代码语言:javascript
复制
data = dict(Machine=None)
data['Machine'] = added_dict = dict(node_labels='+> tfs vs2022')
print('data 1', data)
added_dict['vs'] ='vs2022'
print('data 2', data)

现在,在第二个输出中有两个键:

代码语言:javascript
复制
data 1 {'Machine': {'node_labels': '+> tfs vs2022'}}
data 2 {'Machine': {'node_labels': '+> tfs vs2022', 'vs': 'vs2022'}}

如果您还不知道可以在其中添加密钥,则可以使用.setdefault,可以使用键值辅助,也可以使用.update (用于一次更新多个键):

代码语言:javascript
复制
data = dict()
data.setdefault('Machine', {})['node_labels'] = '+> tfs vs2022'
print('data 1', data)
data.setdefault('Machine', {}).update(dict(vs='vs2022'))
print('data 2', data)
代码语言:javascript
复制
data 1 {'Machine': {'node_labels': '+> tfs vs2022'}}
data 2 {'Machine': {'node_labels': '+> tfs vs2022', 'vs': 'vs2022'}}

当然,您可以将node_labelsvs放在一个dict中并进行赋值,但这将覆盖从YAML加载的任何现有键值。因此,使用.update更好:

代码语言:javascript
复制
import sys
from pathlib import Path
import ruamel.yaml

file_in = Path('input.yaml')
# key in YAML mapping with null value
file_in.write_text("""\
WIN:
""")
    
yaml = ruamel.yaml.YAML()
data = yaml.load(file_in)
if data['WIN'] is None:
    data['WIN'] = {}
data['WIN'].setdefault('Machine', {}).update(dict(node_labels='+> tfs vs2022'))
data['WIN'].setdefault('Machine', {}).update(dict(vs='vs2022'))
yaml.dump(data, sys.stdout)

这给了你预期的结果:

代码语言:javascript
复制
WIN:
  Machine:
    node_labels: +> tfs vs2022
    vs: vs2022
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74669180

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档