【问题标题】:Set value for a nested key in YAML在 YAML 中为嵌套键设置值
【发布时间】:2024-01-22 11:50:01
【问题描述】:

我需要一个允许在 YAML 文件中设置嵌套值的函数。例如,对于像这样的 YAML:

  • 级别_1:
    • 级别_2:
      • LEVEL_3:一些值

我会这样做: update_yaml_value("LEVEL_1.LEVEL_2.LEVEL_3", "new_value")

如果有任何帮助,我将不胜感激。提前致谢。

【问题讨论】:

    标签: python python-3.x yaml


    【解决方案1】:

    首先你需要导入yaml:

    import yaml
    

    当你加载一些 yaml 文件时,你会得到一个 python dict 对象。

    with open('/path/to/smth.yaml', 'r') as f:
        yaml_data = yaml.safe_load(f)
    

    要能够按照您描述的方式更改它,您可以创建如下函数:

    def update_yaml_value(long_key, data):
        keys = long_key.split('.')
        accessable = yaml_data
        for k in keys[:-1]:
            accessable = accessable[k]
        accessable[keys[-1]] = data
    

    然后保存这个yaml文件:

    with open('/path/to/smth.yaml', 'w+') as f:
        yaml.dump(yaml_data, f, default_flow_style=False)
    

    【讨论】:

      【解决方案2】:

      您的 python 代码将 load 将 YAML 转换为字典。

      使用 dict,您将能够更新值。

      a_dict = load_yaml() # to be implemented by the OP
      a_dict['level_1']['level_2']['level_3'] = 'a_new_value'
      

      【讨论】:

        【解决方案3】:

        你可以使用这个函数来改变字典的值。

        test.py:

        #!/usr/bin/env python3
        
        import yaml
        
        
        def change_config(conf, key, value):
            if isinstance(conf, dict):
                for k, v in conf.items():
                    if k == key:
                        conf[k] = value
                    elif isinstance(v, dict):
                        change_config(v, key, value)
        
        
        with open("smth.yaml", "r") as f:
            yaml_data = yaml.load(f, Loader=yaml.Loader)
            print(yaml_data)
            change_config(yaml_data, "level3", "hassan")
            print(yaml_data)
        

        smth.yaml:

        level0:
          level1:
            level3: test
        

        终端输出:

        {'level0': {'level1': {'level3': 'test'}}}
        {'level0': {'level1': {'level3': 'hassan'}}}
        

        【讨论】:

        • 如果我能保证键是唯一的,这个会很好用。在我的情况下,他们不会。谢谢你。