Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing dict "values" like an attribute?

What I am looking for is having something like this:

self.info['key'].attr2

But I'm not sure what would be the most elegant way to achieve it. So far I have defined a dictionary like below but don't have attributes from it.

self.info  = {}
self.info.update({'key':
                        {'attr1':   2,
                         'attr2':   lambda: self.func(arg1)}
                       })

But then I would have to use it like:

self.info['key']['attr2']()

Note that what I am looking for is accessing the dictionary values like attributes. This thread has an answer which can be used in my case also probably that is I make an object out of the sub-dictionary from above and give it as a value to the main dictionary.

But I wonder if there is nicer way, perhaps with decorators and with less lines of codes and maybe even without using dictionaries do to something like what I described in the first line, perhaps even better like:

self['key'].attr2
like image 575
azerila Avatar asked Mar 14 '20 15:03

azerila


3 Answers

Here is a short wrapper to access dict keys as attributes:

class nameddict(dict):
   __getattr__ = dict.__getitem__

info = nameddict()
info['key'] = nameddict(attr1=2, attr2=3)

Then info['key'].attr2 as well as info['key']['attr2'] and info.key.attr2 returns 3.

like image 152
Friedrich Avatar answered Oct 02 '22 16:10

Friedrich


if you want a more dynamic container for which you don't need to declare the attributes like in namedtuple you can use SimpleNamespace object.

from types import SimpleNamespace as ns
info  = {}
info.update({'key': ns(attr1=2, attr2=lambda x: x+1)})
like image 22
Lior Cohen Avatar answered Oct 02 '22 15:10

Lior Cohen


You could use collections.namedtuple, as suggested in the thread you link:

Attrs = namedtuple("Attrs", ["attr1", "attr2"])
info = {"key": Attrs(attr1=2, attr2=lambda: 4)}
info["key"].attr2()
like image 39
dspencer Avatar answered Oct 02 '22 16:10

dspencer