这是我的示例YAML文件,
# Employee records
Developer:
Department: IT
Manager: ABCD
Floor: 2nd
Lab: 4
Support:
Department: General
Manager: XYZ
Floor: 1st
Lab: 1
Martin:
name: Martin Devloper
job: Developer
skills:
- python
我想从特定目录中读取此yaml文件,对其进行编辑,然后将编辑后的文本保存在同一yaml文件中。我从某个地方的链接获得了以下代码:
import sys
from ruamel.yaml import YAML
inp_fo = open("C:/<Users>/Master
1TB/source/repos/New_insertdata/PythonApplication3/inp.yaml").read()
#Read the YAML File
yaml = YAML()
code = yaml.load(inp_fo)
sys.stdout.write('\n')
code.insert(1, 'sensor', 'None', comment="new key")
inp_fo2 = open("inp.yaml","w") #Open the file for Write
yaml.dump(code, inp_fo2) ##Write to file with new parameter
inp_fo2.close() ## close the file
当我执行它时,输出如下:
# Employee records
Developer:
Department: IT
Manager: ABCD
Floor: 2nd
Lab: 4
Support:
Department: General
Manager: XYZ
Floor: 1st
Lab: 1
Martin:
name: Martin
job: Developer
skills:
- python
Tabitha: None
但是我需要:
# Employee records
Developer:
Department: IT
Manager: ABCD
Floor: 2nd
Lab: 4
Support:
Department: General
Manager: XYZ
Floor: 1st
Lab: 1
Martin:
name: Martin
job: Developer
skills:
- python
Tabitha:
name: Tabitha Bitumen
job: Developer
skills:
- Java
如何编写此代码?
我为“ Tabitha”输入的值为“无”,因为如果不为其插入值,code.insert不会被执行。
现在,我想重复编辑此yaml文件,以便为每个键值定义一个变量,因此,每次变量值更改后,将执行代码,并将新的键值插入到现有的yaml文件中。我不想删除YAML文件的早期内容,只需要继续添加新内容(键和值)(内容将是员工详细信息,例如姓名,职位,技能)。
我对这种编码语言是完全陌生的,所以如果我错了,请纠正我。还有谁能向我解释ruamel.yaml中缩进,序列和映射的用途以及如何在代码中使用它们?
我是一名学习者,上面的示例是一个随机的yaml文件,仅是学习ruamel.yaml的示例。
让我向您解释我到底想要什么, 以下内容将保持不变。
# Employee records
Developer:
Department: IT
Manager: ABCD
Floor: 2nd
Lab: 4
Support:
Department: General
Manager: XYZ
Floor: 1st
Lab: 1
但是关键值(员工详细信息)将发生变化。我想要的示例: 马丁: 名称:马丁·德洛普特 职位:开发人员 技能: -蟒蛇
"Martin" should be a "variableP"
name: "variableQ"
job: "variableR"
skills:
- "variableS"
类似地,如果另一个雇员添加了他的详细信息,则代码将自动在这些变量中添加另一个雇员的详细信息。 因为根据您的代码,我将不得不反复添加
code['Tabitha'] = dict(name='Tabitha Bitumen', job='Developer', skills=['Java'])
再次对于我不想要的其他员工数据,我只想要一个代码,我可以在其中定义一个变量,其值将不断变化,并将重复编辑相同的yaml文件,并且不会删除以前的员工详细信息。 没有要添加的员工列表的限制,所以我不想一次又一次地编辑代码。
我基本上了解C和arduino编程语言,因此寻找一种在代码中定义变量的方法,这将使我的工作变得容易。
答案 0 :(得分:0)
您使用的YAML库在YAML格式和Python字典之间转换。因此,您可以简单地编辑字典以在YAML文件中添加或更改值。例如:
import sys
from ruamel.yaml import YAML
filename = "C:/<Users>/Master/1TB/source/repos/New_insertdata/PythonApplication3/inp.yaml"
yaml = YAML()
with open(filename) as inp_fo:
code = yaml.load(inp_fo)
code["Tabitha"] = {
"name":"Tabitha Bitman",
"job":"Developer",
"skills":["Python"]
}
with open(filename, "w") as file:
yaml.dump(code, file) ##Write to file with new parameter
在“ with”中打开文件时,无需关闭文件 声明
假设您其余代码正确,这将更新YAML文件中Tabitha的详细信息。
您还可以将变量解析为key:value查找,将code["Tabitha"]
替换为code[variable_name]
。
如果您正在使用YAML(或JSON)文件,我也强烈建议您研究并理解Python中的字典。
答案 1 :(得分:0)
以下假设您使用的是Python3(如果您使用的是
学习Python),因为它使用了标准中的pathlib
Python3库。有一个
pathlib2
软件包提供了
Python2的功能。
您提供的示例代码做了一些奇怪的事情:
不必读取文件的内容
(open(...).read()
),然后将其交给.load()
方法,
可以直接传递文件指针(即
做open()
,或者您可以使用Path
对象并将其交给
.load()
甚至没有打开文件(如下所示)。
尚不清楚为什么将换行符写入sys.stdout
,实际上
在此代码段中没有功能
调用code.insert(1, 'sensor', 'None', comment="new key")
确实将'sensor'设置为
像对象code
一样在词典中在位置1 的新键,其值为None
和行尾注释“新键”。 (位置计数从0开始。
如果您确实运行过该代码,则将获得输出:
# Employee records
Developer:
Department: IT
Manager: ABCD
Floor: 2nd
Lab: 4
sensor: None # new key
Support:
Department: General
Manager: XYZ
Floor: 1st
Lab: 1
Martin:
name: Martin Devloper
job: Developer
skills:
- python
在您的输入文件的根部是带有键Developer
的映射,
Support
和Martin
。与键关联的值可以再次是
映射(所有根级密钥都是这种情况),但是它们可以
也是一个序列(如skills
的值,用破折号表示
({-
)或标量值(字符串,数字等)。 YAML的根
文档可以是标量(这是标量中唯一的对象
文档)或序列。序列中的元素可以是
标量(作为您的最后一行python
),但这些元素也可以是
映射或其他序列。
映射作为Python dict
加载,序列作为Python加载
list
个。为了保留评论(和其他信息),
ruamel.yaml
将创建字典。用作列表的对象
在这个例子中。您将无法定期拨打code.insert()
Python dict
,但您可以根据从YAML().load()
获得的内容进行操作
如果您只想在字典末尾添加键值对,则无需
使用.insert
,您可以执行以下操作:
code['Tabitha'] = dict(name='Tabitha Bitumen', job='Developer', skills=['Java'])
如果您需要将某些内容移到YAML文件的末尾,则实际上无法 只需使用例如
code['Support'] = dict(Department='General', Manager='KLM', Floor='1st', Lab=1)
这将使您的键/值位于旧位置。您必须要做
del code['Support']
首先让它忘记这个旧职位。
如前所述,ruamel.yaml
支持多种阅读和阅读方式。
写入文件。引入了with
作为Moralous
的答案
比显式打开,阅读和关闭要好。您也可以使用
pathlib.Path
类似于使用.load()
和.dump()
方法的对象:
from pathlib import Path
from ruamel.yaml import YAML
path = Path('inp.yaml') # I shortened this a bit, as I don't have a C: drive
opath = Path('outp.yaml')
yaml = YAML()
code = yaml.load(path)
code['Tabitha'] = dict(name='Tabitha Bitumen', job='Developer', skills=['Java'])
yaml.dump(code, opath)
给出:
# Employee records
Developer:
Department: IT
Manager: ABCD
Floor: 2nd
Lab: 4
Support:
Department: General
Manager: XYZ
Floor: 1st
Lab: 1
Martin:
name: Martin Devloper
job: Developer
skills:
- python
Tabitha:
name: Tabitha Bitumen
job: Developer
skills:
- Java
这几乎是您想要的,但是YAML输出的默认缩进 对于dict(如您所愿)和 序列(它被计入元素的开头,而不是 破折号)。
要获得所需的内容,您需要为序列指定四个缩进,并且
破折号的两个偏移量与空格的偏移量。您可以通过插入,
在yaml = YAML()
行之后,一行带有:
yaml.indent(sequence=4, offset=2)
您也可以在YAML
语句中使用with
实例本身:
import sys
from pathlib import Path
from ruamel.yaml import YAML
path = Path('inp.yaml') # I shortened this a bit, as I don't have a C: drive
opath = Path('outp.yaml')
with YAML(output=opath) as yaml:
yaml.indent(sequence=4, offset=2)
code = yaml.load(path)
code['Tabitha'] = dict(name='Tabitha Bitumen', job='Developer', skills=['Java'])
yaml.dump(code)
这也将为您提供想要的东西:
# Employee records
Developer:
Department: IT
Manager: ABCD
Floor: 2nd
Lab: 4
Support:
Department: General
Manager: XYZ
Floor: 1st
Lab: 1
Martin:
name: Martin Devloper
job: Developer
skills:
- python
Tabitha:
name: Tabitha Bitumen
job: Developer
skills:
- Java
您也用PyYAML标记了您的问题。请注意,使用该包装 您无法执行上述操作:您在YAML文件中的评论将丢失,并且 您没有对缩进的精细控制来获得结果 想要的。
答案 2 :(得分:0)
在研究这个YAML的过程中,我发现了问题,并认为如果能帮助其他人更好地理解,可以分享解释。 YAML是配置文件,我们可以使用python中的YAML解析器解析JSON格式。 我们可以使用ruamel.yaml PYPI模块在python中构建解析器。
这是示例YAML config.yaml文件:-
# Employee records
Developer:
Department: IT
Manager: ABCD
Floor: 2nd
Lab: 4
Support:
Department: General
Manager: XYZ
Floor: 1st
Lab: 1
Martin:
name: Martin Devloper
job: Developer
skills:
- python
Kavya:
name: Kavya Agarwal
job: Developer
skills:
- Java
Atharv:
Name: 190.22.45.33
Job: Smriti
Skills:
- python
这里我附上了YAML解析器代码:-
from ruamel.yaml import YAML
filepath = 'config.yaml'
def yaml_loader(file_path):
yaml = YAML()
with open(file_path) as fp:
yaml.indent(sequence=4, offset=2)
data = yaml.load(fp)
data['Atharv'] = {
"Name":"190.22.45.33",
"Job":"Smriti",
"Skills":["python"]
}
with open(file_path, "w") as file:
yaml.dump(data, file)
yaml_loader("config.yaml")