使用 Python 更改 yaml 文件中的值
Changing a value in a yaml file using Python
我有一个 .yaml
文件,我想用 Python 代码更新。假设它看起来像这样:
state: 'present'
我想要一个更改状态并保存文件的代码。我正在尝试这样的事情但失败了:
def set_state(state):
with open("file_to_edit.yaml", 'rw') as f:
doc = yaml.load(f)
doc['state'] = state
yaml.dump(f)
我正在为 Python 使用 'yaml' 包。
我猜你没有正确缩进,因为你的函数在其当前状态下似乎没有做任何事情。 Python 关心缩进。
试试这个:
def set_state(state):
with open("file_to_edit.yaml", 'rw') as f:
doc = yaml.load(f)
doc['state'] = state
yaml.dump(f)
问题是 yaml.dump(doc)
实际上并没有写入文件。相反,it returns the modified YAML as a string 除非您也将文件描述符作为参数传递,这允许您直接写入文件。
以下应该有效:
def set_state(state):
with open('file_to_edit.yaml') as f:
doc = yaml.load(f)
doc['state'] = state
with open('file_to_edit.yaml', 'w') as f:
yaml.dump(doc, f)
您可以尝试以下操作(它会创建一个新文件来存储结果):
with open("output_file", 'a') as out:
with open("input_file", 'r') as f:
for line in f:
line = re.sub(r"state: present", "state: installed", line)
out.write(line)
首先:如果没有必要,请永远不要使用 yaml.load()
,因为原则上这样做是不安全的。对于这种简单的结构(没有标签),你应该使用 yaml.safe_load()
(如果你的数据在转储后不能 safe_loaded,相应的 safe_dump()
会抱怨)。
yaml.dump()
具有以下签名:
def dump(documents, stream=None, Dumper=Dumper,
default_style=None, default_flow_style=None,
canonical=None, indent=None, width=None,
allow_unicode=None, line_break=None,
encoding='utf-8', explicit_start=None, explicit_end=None,
version=None, tags=None)
其中只有第一个需要给出,那应该是您的 doc
变量。如果不指定流,则 dump()
将数据结构写入内存中的文件对象(如 StringIO),并在写入 returns 后将值作为字符串。
所以尽管你可以这样做:
with open("file_to_edit.yaml", 'w') as f:
f.write(yaml.safe_dump(doc))
这是低效的,并且对 yaml.safe_dump()
的工作原理知之甚少。
如果你想打开文件进行读写,你必须确保你都重置了文件中的索引并且截断了它的内容。这通常是不值得的,因此重新打开文件进行写入更安全:
def set_state(state):
file_name = "file_to_edit.yaml"
with open(file_name) as f:
doc = yaml.safe_load(f)
doc['state'] = state
with open(file_name, 'w') as f:
yaml.safe_dump(doc, f, default_flow_style=False)
(当然,当你想确保覆盖原始文件时,你将文件名设为变量,这样你就不会输错它)。
如果您不指定 default_flow_style=False
,您的输出将如下所示:
{state: deleted}
输出将不包括输入中 present
周围的多余引号。您也可以指定 default_style="'"
,但这也会在 state
.
周围加上引号
如果丢失引号是个问题并且您确实希望输出看起来像输入,则应该使用 ruamel.yaml
(免责声明我是该包的作者),它可以保留单个字符串上的引号,处理 YAML 1.2(而不是 YAML 1.1)并且还在您的文件中保留注释。
我有一个 .yaml
文件,我想用 Python 代码更新。假设它看起来像这样:
state: 'present'
我想要一个更改状态并保存文件的代码。我正在尝试这样的事情但失败了:
def set_state(state):
with open("file_to_edit.yaml", 'rw') as f:
doc = yaml.load(f)
doc['state'] = state
yaml.dump(f)
我正在为 Python 使用 'yaml' 包。
我猜你没有正确缩进,因为你的函数在其当前状态下似乎没有做任何事情。 Python 关心缩进。
试试这个:
def set_state(state):
with open("file_to_edit.yaml", 'rw') as f:
doc = yaml.load(f)
doc['state'] = state
yaml.dump(f)
问题是 yaml.dump(doc)
实际上并没有写入文件。相反,it returns the modified YAML as a string 除非您也将文件描述符作为参数传递,这允许您直接写入文件。
以下应该有效:
def set_state(state):
with open('file_to_edit.yaml') as f:
doc = yaml.load(f)
doc['state'] = state
with open('file_to_edit.yaml', 'w') as f:
yaml.dump(doc, f)
您可以尝试以下操作(它会创建一个新文件来存储结果):
with open("output_file", 'a') as out:
with open("input_file", 'r') as f:
for line in f:
line = re.sub(r"state: present", "state: installed", line)
out.write(line)
首先:如果没有必要,请永远不要使用 yaml.load()
,因为原则上这样做是不安全的。对于这种简单的结构(没有标签),你应该使用 yaml.safe_load()
(如果你的数据在转储后不能 safe_loaded,相应的 safe_dump()
会抱怨)。
yaml.dump()
具有以下签名:
def dump(documents, stream=None, Dumper=Dumper,
default_style=None, default_flow_style=None,
canonical=None, indent=None, width=None,
allow_unicode=None, line_break=None,
encoding='utf-8', explicit_start=None, explicit_end=None,
version=None, tags=None)
其中只有第一个需要给出,那应该是您的 doc
变量。如果不指定流,则 dump()
将数据结构写入内存中的文件对象(如 StringIO),并在写入 returns 后将值作为字符串。
所以尽管你可以这样做:
with open("file_to_edit.yaml", 'w') as f:
f.write(yaml.safe_dump(doc))
这是低效的,并且对 yaml.safe_dump()
的工作原理知之甚少。
如果你想打开文件进行读写,你必须确保你都重置了文件中的索引并且截断了它的内容。这通常是不值得的,因此重新打开文件进行写入更安全:
def set_state(state):
file_name = "file_to_edit.yaml"
with open(file_name) as f:
doc = yaml.safe_load(f)
doc['state'] = state
with open(file_name, 'w') as f:
yaml.safe_dump(doc, f, default_flow_style=False)
(当然,当你想确保覆盖原始文件时,你将文件名设为变量,这样你就不会输错它)。
如果您不指定 default_flow_style=False
,您的输出将如下所示:
{state: deleted}
输出将不包括输入中 present
周围的多余引号。您也可以指定 default_style="'"
,但这也会在 state
.
周围加上引号
如果丢失引号是个问题并且您确实希望输出看起来像输入,则应该使用 ruamel.yaml
(免责声明我是该包的作者),它可以保留单个字符串上的引号,处理 YAML 1.2(而不是 YAML 1.1)并且还在您的文件中保留注释。