我想访问和修改YAML文件的内容,如下所示:
A: Sonstige
B:
C: Sonstige
D: null
E: 1
我知道为了访问&修改上面YAML文件中A
的值,我会使用如下代码:
def set_state(state):
with open('my_file.yaml') as f:
doc = yaml.load(f)
doc['A'] = state
with open('my_file.yaml', 'w') as f:
yaml.dump(doc, f)
但是如果我想在上面的YAML文件中修改E
的值呢?如何访问E
的值并修改其值并将其转储到YAML文件中,类似于上面的代码。我已经查阅了参考文档,但无法找到答案。
答案 0 :(得分:2)
如果您想更改E
的值,例如到2
您可以执行以下操作:
import yaml
def set_state(state):
with open('my_file.yaml') as f:
doc = yaml.load(f)
doc['B']['E'] = state
with open('my_file.yaml', 'w') as f:
yaml.dump(doc, f)
set_state(2)
在E
上获得B
第一个索引的值。
根据我的经验,这有很多问题:
您正在使用load()
,它在PyYAML中是一个不安全的操作而没有警告。您的数据可以使用safe_load()
加载,即使不能将safe_load()
扩展到处理标记(仅限于那些标记),而不是扩展load()
。
您的输出如下:
A: Sonstige
B: {C: Sonstige, D: null, E: 2}
根本不像你的输入,所以使用选项default_flow_style=False
用原始的块式布局来获得一些东西。
您不需要dump()
,因为可以使用dict
转储由safe_dump()
和基元(和列表)组成的数据。那里没有安全问题,但是如果你不小心使用非原语打电话给set_state()
:
class Dice:
def __init__(self, sides):
self.sides = sides
set_state(Dice(6))
然后dump()
将静默生成非便携式:
A: Sonstige
B:
C: Sonstige
D: null
E: !!python/object:__main__.Dice {sides: 6}
而不是引发Representer
错误。
原始文件中的任何评论都将丢失。 PyYAML不保留这些。
使用PyYAML,你应该这样做:
import yaml
def set_state(state):
with open('my_file.yaml') as f:
doc = yaml.safe_load(f)
doc['B']['E'] = state
with open('my_file.yaml', 'w') as f:
yaml.safe_dump(doc, f, default_flow_style=False)
set_state(2)
如果你还想保留评论,或者想要保留的块式和流式的混合,我建议你使用ruamel.yaml
(免责声明:我是该套餐的作者):< / p>
import pathlib
from ruamel.yaml import YAML
def set_state(state):
yaml = YAML()
mf = pathlib.Path('my_file.yaml')
doc = yaml.load(mf)
doc['B']['E'] = state
yaml.dump(doc, mf)
这与以前的结果相同,默认情况下load()
方法是安全的,保留您的布局(加上您可能拥有的YAML文件中的任何注释)并打开Path
实例进行读取或者根据需要撰写(因此您不需要with
语句,也不需要调用dump
的双重操作并将w
提供给open()
。