在 Python3 中使用 ruamel.yaml 解析 Yaml 嵌套配置
Parsing Yaml nested configuration with ruamel.yaml in Python3
当使用 Python 包 ruamel.yaml
解析 YAML 配置文件时,我需要考虑到在同一个 YAML 文件中可以用两种不同的样式描述嵌套:
- 使用换行和缩进
- 使用点 (.)
简化示例:
logging.yml
# 1. by using new line and indents
logging:
file:
name: app.log
# 2. by using dots (.)
logging.file.path: /logs
main.py
#!/usr/bin/env python3
import ruamel.yaml as yaml
with open('logging.yml', 'r') as file:
data = yaml.safe_load(file)
print(data)
实际输出:
{
'logging': {
'file': {
'name': 'app.log'
}
},
'logging.file.path': '/logs'
}
是否可以以某种方式配置 ruamel.yaml
以便我可以将 path
属性 嵌套在 logging->file 中,如下所述,以便我可以轻松访问属性然后? :
{
'logging': {
'file': {
'name': 'app.log',
'path': '/logs'
}
}
}
不,不可能按照你的方式配置ruamel.yaml
想。我什至认为尝试创建构造函数是个坏主意
那会在加载过程中即时执行您想要的操作,例如意味着你
在解析映射时需要考虑到
这是键 file
的值,一个 python 字典已经可以
由于分裂 logging.file.path
.
而存在
我建议您 post-处理您的 data
:
from pprint import pprint
import ruamel.yaml
yaml_str = """\
logging:
file:
name: app.log
logging.file.path: /logs
"""
yaml = ruamel.yaml.YAML(typ='safe')
data = yaml.load(yaml_str)
for k in list(data.keys()):
if not '.' in k:
continue
keys = k.split('.')
d = data
while len(keys) > 1:
d = d.setdefault(keys.pop(0), {})
d[keys[0]] = data.pop(k)
pprint(data, width=-1)
给出:
{'logging': {'file': {'name': 'app.log',
'path': '/logs'}}}
如有必要,您可以递归地执行此操作,以防您有密钥
根级别不存在的点。
当使用 Python 包 ruamel.yaml
解析 YAML 配置文件时,我需要考虑到在同一个 YAML 文件中可以用两种不同的样式描述嵌套:
- 使用换行和缩进
- 使用点 (.)
简化示例:
logging.yml
# 1. by using new line and indents
logging:
file:
name: app.log
# 2. by using dots (.)
logging.file.path: /logs
main.py
#!/usr/bin/env python3
import ruamel.yaml as yaml
with open('logging.yml', 'r') as file:
data = yaml.safe_load(file)
print(data)
实际输出:
{
'logging': {
'file': {
'name': 'app.log'
}
},
'logging.file.path': '/logs'
}
是否可以以某种方式配置 ruamel.yaml
以便我可以将 path
属性 嵌套在 logging->file 中,如下所述,以便我可以轻松访问属性然后? :
{
'logging': {
'file': {
'name': 'app.log',
'path': '/logs'
}
}
}
不,不可能按照你的方式配置ruamel.yaml
想。我什至认为尝试创建构造函数是个坏主意
那会在加载过程中即时执行您想要的操作,例如意味着你
在解析映射时需要考虑到
这是键 file
的值,一个 python 字典已经可以
由于分裂 logging.file.path
.
我建议您 post-处理您的 data
:
from pprint import pprint
import ruamel.yaml
yaml_str = """\
logging:
file:
name: app.log
logging.file.path: /logs
"""
yaml = ruamel.yaml.YAML(typ='safe')
data = yaml.load(yaml_str)
for k in list(data.keys()):
if not '.' in k:
continue
keys = k.split('.')
d = data
while len(keys) > 1:
d = d.setdefault(keys.pop(0), {})
d[keys[0]] = data.pop(k)
pprint(data, width=-1)
给出:
{'logging': {'file': {'name': 'app.log',
'path': '/logs'}}}
如有必要,您可以递归地执行此操作,以防您有密钥 根级别不存在的点。