I have a configuration file in YAML that is currently loaded as a dictionary using yaml.safe_load. For convenience in writing my code, I'd prefer to load it as a set of nested objects. It's cumbersome to refer to deeper levels of the dictionary and makes the code harder to read.
Example:
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]
""")
Currently, I access items like
mydict["b"][0]["r"]
>>> 99
What I'd like to be able to do is access the same information like
mydict.b[0].r
>>> 99
Is there a way to load YAML as nested objects like this? Or will I have to roll my own class and recursively flip these dictionaries into nested objects? I'm guessing namedtuple could make this a bit easier, but I'd prefer an off-the-shelf solution for the whole thing.
Found a handy library to do exactly what I need: 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)
(I had to write a simple method to recursively convert all subdicts into munches but now I can navigate my data with e.g.
>>> mymunch.b.q
"foo"
Using a SimpleNamespace will work at the top level, but won't translate nested structures.
dct = yaml.safe_load(...)
obj = types.SimpleNamespace(**dct)
To achieve full object-tree translation:
def load_object(dct):
return types.SimpleNamespace(**dct)
dct = yaml.safe_load(...)
obj = json.loads(json.dumps(dct), object_hook=load_object)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With