簡體   English   中英

如何在不覆蓋 python 的情況下將新鍵值添加到 yaml?

[英]How to add new key value to yaml without overwriting it in python?

我有一個小的 python 腳本,它負責通過添加新記錄來更新我的 yaml 文件:

data = yaml.load(file)
data['WIN']['Machine'] = dict(node_labels='+> tfs vs2022')
data['WIN']['Machine'] = dict(vs='vs2022')
yaml.dump(data, file)

每次我運行上面的腳本時,我都會得到更新的 yaml 文件,如下所示:

WIN:
  Machine:
    vs: vs2022

我希望 output 擁有我的兩個鍵:值對

WIN:
  Machine:
    node_labels: +> tfs vs2022
    vs: vs2022

我想知道為什么行data['WIN'][nodeName] = dict(node_labels='+> tfs vs2022')被下一行覆蓋? 如何添加幾個鍵: Machine部分的值?

這不是 YAML 相關問題,而是您的非 yaml 相關 Python 代碼中的概念問題。

通過將字典作為值分配給鍵Machine ,您可以設置該值。 通過將另一個字典分配給該鍵,您可以完全覆蓋該值,從而擦除之前的鍵值對。

如果您簡化代碼:

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不再可用。

data 1 {'Machine': {'node_labels': '+> tfs vs2022'}}
data 2 {'Machine': {'vs': 'vs2022'}}

有幾種方法可以解決這個問題。 您可以為第一個字典中的鍵分配一個值:

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)

現在你在第二個 output 中有了兩個密鑰:

data 1 {'Machine': {'node_labels': '+> tfs vs2022'}}
data 2 {'Machine': {'node_labels': '+> tfs vs2022', 'vs': 'vs2022'}}

如果您還不知道可以在其中添加鍵的字典,您可以使用.setdefault ,使用鍵值分配和/或使用.update (對於一次更新多個鍵很有用) :

data = dict()
data.setdefault('Machine', {})['node_labels'] = '+> tfs vs2022'
print('data 1', data)
data.setdefault('Machine', {}).update(dict(vs='vs2022'))
print('data 2', data)
data 1 {'Machine': {'node_labels': '+> tfs vs2022'}}
data 2 {'Machine': {'node_labels': '+> tfs vs2022', 'vs': 'vs2022'}}

當然,您可以將node_labelsvs放在一個字典中並分配,但這會覆蓋從 YAML 加載的任何現有鍵值。所以使用.update是 IMO 更好:

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)

這給出了您的預期結果:

WIN:
  Machine:
    node_labels: +> tfs vs2022
    vs: vs2022

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM