如何使用python更新yaml文件

2024-04-27 08:23:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个some.yaml文件,包含以下内容。

    init_config: {}
    instances:
        - host: <IP>
          username: <username>
          password: <password>

yaml文件应按如下方式进行分析和更新。

    init_config: {}
    instances:
        - host: 1.2.3.4
          username: Username
          password: Password

如何解析这些值并适当地更新它们?


Tags: 文件instancesipconfighostyamlinit方式
3条回答

这就是我如何从上面提到的文件中读取,根据需要解析和更新。

import yaml

fname = "some.yaml"

stream = open(fname, 'r')
data = yaml.load(stream)

data['instances'][0]['host'] = '1.2.3.4'
data['instances'][0]['username'] = 'Username'
data['instances'][0]['password'] = 'Password'

with open(fname, 'w') as yaml_file:
    yaml_file.write( yaml.dump(data, default_flow_style=False))

ruamel.yaml包被特别增强(由我从PyYAML开始)来执行这种往返、编程、更新。

如果您以(请注意,我删除了额外的初始空格):

init_config: {}
instances:
    - host: <IP>              # update with IP
      username: <username>    # update with user name
      password: <password>    # update with password

然后运行:

import ruamel.yaml

file_name = 'input.yaml'
config, ind, bsi = ruamel.yaml.util.load_yaml_guess_indent(open(file_name))

instances = config['instances']
instances[0]['host'] = '1.2.3.4'
instances[0]['username'] = 'Username'
instances[0]['password'] = 'Password'

with open('output.yaml', 'w') as fp:
    yaml.dump(config, fp)

输出为:

init_config: {}
instances:
    - host: 1.2.3.4           # update with IP
      username: Username      # update with user name
      password: Password      # update with password

映射键(hostusernamepassword)的顺序、样式和注释都将被保留,而无需任何进一步的特定操作。

与猜测缩进和块序列缩进不同,您可以手动执行传统加载,并自行设置缩进值:

yaml = ruamel.yaml.YAML()
yaml.indent(mapping=6, sequence=4)
with open(file_name) as fp:
    config = yaml.load(fp)

如果您查看这个答案的历史,您可以看到如何使用一个更有限的、类似PyYAML的API来实现这一点。

我不知道你是否需要山药。除了使用YAML标记之外,您似乎对YAML文档没有兴趣。那么为什么不使用Jinja2或一些模板语言呢?

from jinja2 import Template

tmpl = Template(u'''\
    init_config: {}
    instances:
         - host: {{ IP }}
           username: {{ username }}
           password: {{ password }}
''')

print tmpl.render(
     IP=u"1.2.3.4",
     username=u"Username",
     password=u"Password"
)

我不知道这是否是一个好主意,但是如果您只需要获得一个更改了一些字段的文件,您不需要真正解析YAML文档,并且可以直接从模板语言中获益。


奖励:用例

我处理过非常复杂的YAML文档,其中有未知的标记

...
  propertiesIDs: { 1, 2, 3, 4 }
  globalID: !myapplication.InterfaceID &primitiveID

replication: !myapplication.replication
  beginDate: 2012-09-10T20:00:03
  endDate: 2020-09-10T20:00:04
  replicant_uuid:
    ? 17169504-B6AB-11E4-8437-36E258BB2172
    ? 206B5842-B6AB-11E4-AAC3-36E258BB2172
...

执行此文档的有效分析既困难又耗时。我只需要填充一些值,然后将YAML发送到第三方应用程序。因此,直接通过模板生成有效文档比解析YAML或直接使用pyyaml生成有效文档更简单(更省时,不易出错)。此外,模板语言可以很容易地与循环一起使用,以填充动态大小的字段。

相关问题 更多 >