I'm searching for an elegant way to get data using attribute access on a dict with some nested dicts and lists (i.e. javascript-style object syntax).
For example:
>>> d = {'a': 1, 'b': {'c': 2}, 'd': ["hi", {'foo': "bar"}]}
Should be accessible in this way:
>>> x = dict2obj(d)
>>> x.a
1
>>> x.b.c
2
>>> x.d[1].foo
bar
I think, this is not possible without recursion, but what would be a nice way to get an object style for dicts?
This should get your started:
It doesn't work for lists, yet. You'll have to wrap the lists in a UserList and overload
__getitem__
to wrap dicts.Usage:
My dictionary is of this format:
As can be seen, I have nested dictionaries and list of dicts. This is because the addr_bk was decoded from protocol buffer data that converted to a python dict using lwpb.codec. There are optional field (e.g. email => where key may be unavailable) and repeated field (e.g. phone => converted to list of dict).
I tried all the above proposed solutions. Some doesn't handle the nested dictionaries well. Others cannot print the object details easily.
Only the solution, dict2obj(dict) by Dawie Strauss, works best.
I have enhanced it a little to handle when the key cannot be found:
Then, I tested it with:
What about just assigning your
dict
to the__dict__
of an empty object?Of course this fails on your nested dict example unless you walk the dict recursively:
And your example list element was probably meant to be a
Mapping
, a list of (key, value) pairs like this:x.__dict__.update(d)
should do fine.Here's another implementation:
[Edit] Missed bit about also handling dicts within lists, not just other dicts. Added fix.