我有以下示例YAML文件:
---
test:
name: "Tom"
age: "5"
version: "1.0"
如何将此YAML文件替换为此:
test:
name: "Max"
age: "10"
version: "2.2"
这是我打开文件的方式:
import yaml
with open("config.yml", 'r') as stream:
print(yaml.load(stream))
但是我不知道如何立即编辑YAML文件。
答案 0 :(得分:2)
鉴于您使用PyYaml
的事实,执行此操作的适当方法如下:
#!/usr/bin/env python
import yaml
with open("testfile.yaml", 'r') as stream:
try:
loaded = yaml.load(stream)
except yaml.YAMLError as exc:
print(exc)
# Modify the fields from the dict
loaded['test']['name'] = "Max"
loaded['test']['age'] = "10"
loaded['test']['version'] = "2.2"
# Save it again
with open("modified.yaml", 'w') as stream:
try:
yaml.dump(loaded, stream, default_flow_style=False)
except yaml.YAMLError as exc:
print(exc)
因此,您只需将Yaml加载到名为dict
的{{1}}中,然后修改所需的值,然后保存(调用时是否覆盖原始文件)。对于嵌套输入,您必须具有嵌套字典。 loaded
参数对于产生所需的格式(流样式)是必需的,否则对于嵌套集合,它将产生块样式:
default_flow_style=False
干杯!
稍后修改:
正如Anthon所指出的,我的回答有一些缺陷。
最好使用A: a
B: {C: c, D: d, E: e}
而不是safe_load
,因为后者有潜在危险。
输出需要一个指令结束指示符(开头三个破折号)。要附加它们,我们在load
方法中使用explicit_start=True
(实际上应该是dump
)。
如果要生成更好的输出(尽管它们在语义上相同),则可以使用safe_dump
而不是ruamel.yaml
请参阅Anthon的答案以获取更详细的信息,因为他是该软件包的作者。
答案 1 :(得分:2)
如果您阅读了PyYAML文档,将会发现它
告诉您使用load()
函数具有潜在的危险,
所以要做的第一件事(因为你,几乎其他所有人都没有
需要它),而不是使用它,而是使用safe_load()
。
您还应该将输入文件更改为config.yaml
,
自2006年以来,用于.yaml
的YAML文件recommended extension。
知道了,使用PyYAML更改config.yaml
文件的方法:
import yaml
with open('config.yaml') as stream:
data = yaml.safe_load(stream)
test = data['test']
test.update(dict(name="Tom", age="10", version="2.2"))
with open('output.yaml', 'wb') as stream:
yaml.safe_dump(data, stream, default_flow_style=False,
explicit_start=True, allow_unicode=True, encoding='utf-8')
这将为您提供一个output.yaml
,其外观如下:
---
test:
age: '10'
name: Tom
version: '2.2'
default_flow_style
参数是必需的,这样才能不获取JSON之类的信息
叶节点映射的结构。 explicit_start
获取
前导指标结束指示符(---
),建议您始终使用
allow_unicode=True, encoding='utf-8'
(并以二进制文件打开文件)
为了避免在您更改name
时遇到意外或问题
到Björk Guðmundsdóttir
。
现在,您将注意到,这不会生成您想要的输出 (尽管在语义上是相同的):
Tom
周围没有双引号如果YAML文件中有任何注释,这些注释将丢失。
更新YAML文件的更好方法是使用ruamel.yaml
(免责声明:我是该软件包的作者),其中还有更多内容
没有PyYAML的默认值,处理YAML 1.2且不删除注释
(如果您将它们保存在文件中):
import ruamel.yaml
yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True
yaml.explicit_start = True
with open('config.yaml') as stream:
data = yaml.load(stream)
test = data['test']
test.update(dict(name="Tom", age="10", version="2.2"))
with open('output.yaml', 'wb') as stream:
yaml.dump(data, stream)
您的输出文件将是:
---
test:
name: "Tom"
age: "10"
version: "2.2"
这正是您想要的。