将 YAML 加载为嵌套对象而不是 Python 中的字典

spe*_*eps 3 python yaml

我在 YAML 中有一个配置文件,当前使用 yaml.safe_load 作为字典加载。为了方便编写我的代码,我更愿意将它作为一组嵌套对象加载。引用字典的更深层次很麻烦,并且使代码更难阅读。

例子:

import yaml
mydict = yaml.safe_load("""
a: 1
b:
- q: "foo"
  r: 99
  s: 98
- x: "bar"
  y: 97
  z: 96
c:
  d: 7
  e: 8
  f: [9,10,11]
""")
Run Code Online (Sandbox Code Playgroud)

目前,我访问诸如

mydict["b"][0]["r"]
>>> 99
Run Code Online (Sandbox Code Playgroud)

我希望能够做的是访问相同的信息,如

mydict.b[0].r
>>> 99
Run Code Online (Sandbox Code Playgroud)

有没有办法像这样将 YAML 加载为嵌套对象?或者我是否必须滚动自己的类并递归地将这些字典翻转为嵌套对象?我猜namedtuple可以让这更容易一些,但我更喜欢整个事情的现成解决方案。

spe*_*eps 7

找到了一个方便的库来做我需要的事情:https : //github.com/Infinidat/munch

import yaml
from munch import Munch
mydict = yaml.safe_load("""
a: 1
b:
- q: "foo"
  r: 99
  s: 98
- x: "bar"
  y: 97
  z: 96
c:
  d: 7
  e: 8
  f: [9,10,11]
""")
mymunch = Munch(mydict)
Run Code Online (Sandbox Code Playgroud)

(我必须编写一个简单的方法来递归地将所有 subdicts 转换为 munches,但现在我可以使用例如导航我的数据

>>> mymunch.b.q
"foo"
Run Code Online (Sandbox Code Playgroud)


小智 5

使用 aSimpleNamespace将在顶层工作,但不会转换嵌套结构。

dct = yaml.safe_load(...)
obj = types.SimpleNamespace(**dct)
Run Code Online (Sandbox Code Playgroud)

要实现完整的对象树转换:

def load_object(dct):
    return types.SimpleNamespace(**dct)

dct = yaml.safe_load(...)
obj = json.loads(json.dumps(dct), object_hook=load_object)
Run Code Online (Sandbox Code Playgroud)