pyyaml和yaml子级

2024-05-19 02:13:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我´我试图使用PyYAML将YAML文件解析为python对象

然而,我在课程中提出了疑问

我有YAML文件

first_lvl:
   second_lvl:
       item_a:
          - value_a : "value aaa"
          - value_b : "value bbb"

我的python脚本读取YAML并将其加载到一个对象中

import yaml

class Struct:
    def __init__(self, **entries):
        self.__dict__.update(entries)

with open(job_file.yml) as f:
    skeleton = yaml.full_load(f)

MyJob = Struct(**skeleton)

print(MyJob.first_lvl)

这很好,但只适用于YAML的第一级。如果我想获得yaml文件的子级值,而这些子级值应该包含在对象中呢

像这样:

    print(MyJob.first_lvl.second_lvl) 

它可能与PyYAML模块以及python处理对象的方式无关,但我´我还是迷路了

有人能给我点灯光吗


Tags: 文件对象selfyamlvaluestructskeletonpyyaml
1条回答
网友
1楼 · 发布于 2024-05-19 02:13:26

在您的评论中,您表示您只希望有一个 Struct实例已加载。但是,如果要访问 "value aaa"通过写作 my_job.first_lvl.second_lvl.item_a.0.value_a,你不能这样做 通过提供__getattr__方法,因为这将抛出一个错误 声明dict对象没有属性second_lvl(它只 有一个键second_lvl)。__getattr__永远不会被调用,因为, 在Struct实例上,属性查找不会失败

您可以提供一些方法lookup,该方法作为参数采用“点式”字符串:

import ruamel.yaml

yaml_str = """\
first_lvl:
   second_lvl:
       item_a:
          - value_a : "value aaa"
          - value_b : "value bbb"
"""

class Struct:
    def __init__(self, **entries):
        self.__dict__.update(entries)

    def lookup(self, s):
        def recurse(d, names):
            name = names[0]
            if isinstance(d, list):  # list indices cannot be strings
                name = int(name)                
            if len(names) > 1:
                return recurse(d[name], names[1:])
            return d[name]

        names = s.split('.')
        return recurse(getattr(self, names[0]), names[1:])

yaml = ruamel.yaml.YAML(typ='safe')
my_job = Struct(**yaml.load(yaml_str))

print(my_job.lookup("first_lvl.second_lvl.item_a.0.value_a"))

它给出:

value aaa

This answer显示了另一种扩展方法 在往返模式下使用ruamel.yaml时的默认数据结构

如果你真的想写 my_job.first_lvl.second_lvl.item_a.0.value_a,不带引号,I 别以为有办法让每一层都意识到 设置属性。这意味着扩展Struct,所以 类可以从映射序列构造。这是可以做到的 装载YAML后,但IMO最好在YAML施工期间完成

相关问题 更多 >

    热门问题