L.K*_*ing 4 python yaml pyyaml
我有这个示例 YAML 文件:
---
test:
name: "Tom"
age: "5"
version: "1.0"
Run Code Online (Sandbox Code Playgroud)
如何将此 YAML 文件替换为:
test:
name: "Max"
age: "10"
version: "2.2"
Run Code Online (Sandbox Code Playgroud)
这是我打开文件的方式:
import yaml
with open("config.yml", 'r') as stream:
print(yaml.load(stream))
Run Code Online (Sandbox Code Playgroud)
但我现在不知道如何编辑 YAML 文件。
鉴于您使用 的事实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)
Run Code Online (Sandbox Code Playgroud)
因此,您只需将 yaml 加载到被dict调用的文件中loaded,修改所需的值,然后保存它(是否覆盖原始文件,您的调用)。对于嵌套输入,您将有一个必须修改的嵌套字典。该default_flow_style=False参数对于生成您想要的格式(流样式)是必需的,否则对于嵌套集合,它会生成块样式:
A: a
B: {C: c, D: d, E: e}
Run Code Online (Sandbox Code Playgroud)
干杯!
稍后编辑:
正如安东指出的,我的回答有一些缺陷。
最好使用safe_load而不是load因为后者有潜在的危险。
输出需要一个指令结束指示符(开头的三个破折号)。为了附加它们,我们explicit_start=True在dump方法中使用(实际上应该是safe_dump)。
如果您想生成更好的输出,请使用 Mayberuamel.yaml代替(尽管它们在语义上是相同的)yaml
有关更详细的信息,请参阅 Anthon 的答案,因为他是该包的作者。
如果您通读 PyYAML 文档,您会发现它\n告诉您使用该load()函数有潜在危险,\n因此要做的第一件事(因为您和几乎其他人都不需要\n)不是使用它,但使用safe_load()代替。
您还应该将输入文件更改为config.yaml,自 2006 年起,\n就开始推荐YAML 文件的扩展名.yaml。
config.yaml知道了这一点,使用 PyYAML更改文件的方法:
import yaml\n\nwith open(\'config.yaml\') as stream:\n data = yaml.safe_load(stream)\n\ntest = data[\'test\']\ntest.update(dict(name="Tom", age="10", version="2.2"))\n\nwith open(\'output.yaml\', \'wb\') as stream:\n yaml.safe_dump(data, stream, default_flow_style=False, \n explicit_start=True, allow_unicode=True, encoding=\'utf-8\')\nRun Code Online (Sandbox Code Playgroud)\n\n这会给你一个output.yaml看起来像这样的:
---\ntest:\n age: \'10\'\n name: Tom\n version: \'2.2\'\nRun Code Online (Sandbox Code Playgroud)\n\n该default_flow_style参数对于不获取类似 JSON 的叶节点映射\n结构是必需的。来explicit_start获取\n前导指令结束指示符 ( ---),我建议始终使用\n (并将文件作为二进制文件打开)\n,以便在更改为\nallow_unicode=True, encoding=\'utf-8\'时不会遇到意外或问题。nameBj\xc3\xb6rk Gu\xc3\xb0mundsd\xc3\xb3ttir
现在您会注意到,这不会生成您想要的输出(尽管语义上相同):
\n\nTom如果您在 YAML 文件中有任何注释,这些注释将会丢失。
\n\n更新 YAML 文件的更好方法是使用ruamel.yaml\n(免责声明:我是该包的作者),它比 PyYAML 有更多\ns任何默认值,处理 YAML 1.2 并且不会删除注释\n(如果您有它们在你的文件中):
import ruamel.yaml\n\n\nyaml = ruamel.yaml.YAML()\nyaml.preserve_quotes = True\nyaml.explicit_start = True\n\nwith open(\'config.yaml\') as stream:\n data = yaml.load(stream)\n\ntest = data[\'test\']\ntest.update(dict(name="Tom", age="10", version="2.2"))\n\nwith open(\'output.yaml\', \'wb\') as stream:\n yaml.dump(data, stream)\nRun Code Online (Sandbox Code Playgroud)\n\n这样你的输出文件将是:
\n\n---\ntest:\n name: "Tom"\n age: "10"\n version: "2.2"\nRun Code Online (Sandbox Code Playgroud)\n\n这正是你想要的。
\n| 归档时间: |
|
| 查看次数: |
14512 次 |
| 最近记录: |