【问题标题】:Parsing Yaml nested configuration with ruamel.yaml in Python3在 Python3 中使用 ruamel.yaml 解析 Yaml 嵌套配置
【发布时间】:2019-11-27 19:02:44
【问题描述】:

在使用 Python 包 ruamel.yaml 解析 YAML 配置文件时,我需要考虑到嵌套可以在同一个 YAML 文件中以两种不同的样式描述:

  1. 使用新行和缩进
  2. 使用点 (.)

简化示例:

运行repl.it snippet

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': {
      'name': 'app.log',
      'path': '/logs'
    }
  }
}

【问题讨论】:

  • 我看不出如何通过使用数据的内置打印来获得实际输出,所有内容都应该出现在一行上。
  • 实际输出的漂亮打印只是为了便于阅读,而不是我在代码中关心的内容。应该在帖子中提到这一点,对此感到抱歉

标签: python-3.x ruamel.yaml


【解决方案1】:

不,不能以您的方式配置ruamel.yaml 想。我什至认为尝试创建构造函数是个坏主意 这将在加载过程中即时执行您想要的操作,例如意味着你 在解析映射时需要考虑到 那是键 file 的值,python 字典可能已经 由于拆分logging.file.path而存在。

我建议您对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'}}}

如有必要,您可以递归地执行此操作,以防您有 根级别不存在的点。

【讨论】:

    猜你喜欢
    • 2021-12-24
    • 2018-12-21
    • 2017-11-17
    • 2018-08-07
    • 2017-11-28
    • 2019-07-23
    • 2012-02-16
    • 2016-09-12
    • 2019-01-23
    相关资源
    最近更新 更多