如何从python访问和修改yaml文件的内容?
How to access & modify the content of yaml file from python?
我想访问和修改如下所示的 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 文件中,类似于上面的代码。我已经查看了参考文档,但无法找到答案。
如果您想更改 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()
.[=38 要好得多=]
你的输出看起来像:
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
(免责声明:我是那个包的作者) :
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()
)。
我想访问和修改如下所示的 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 文件中,类似于上面的代码。我已经查看了参考文档,但无法找到答案。
如果您想更改 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()
.[=38 要好得多=]你的输出看起来像:
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
(免责声明:我是那个包的作者) :
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()
)。