views:

228

answers:

2

How do I make Python dictionary members accessible via a dot "."?

For example, instead of writing mydict['val'], I'd like to write mydict.val.

Also I'd like to access nested dicts this way. For example, mydict.mydict2.val would refer to mydict = { 'mydict2': { 'val': ... } }.

Thanks, Boda Cydo.

+5  A: 

Derive from dict and and implement __getattr__ and __setattr__.

Or you can use Bunch which is very similar.

I don't think it's possible to monkeypatch built-in dict class.

Kugel
Correct. You can't monkeypatch `dict` (thank god).
Mike Graham
What does monkeypatch mean exactly? I have heard about it but not used. (Sorry that I ask such newbie questions, I am not that good with programming yet (I'm only 2nd year student.))
bodacydo
Monkeypatching is using the dynamicity of Python (or whatever language) to change something that would usually be defined in source code. It especially applies to changing the definition of classes after they are created.
Mike Graham
I see. Thanks for the answer, Mike.
bodacydo
+1  A: 

Don't. Attribute access and indexing are separate things in Python, and you shouldn't want them to perform the same. Make a class (possibly one made by namedtuple) if you have something that should have accessible attributes and use [] notation to get an item from a dict.

Mike Graham
Thanks for the answer. But take a look at this question that I also just asked: http://stackoverflow.com/questions/2352252/how-to-use-dicts-in-mako-templates This seems like a good idea to use `.` instead of `[]` to access complicated data structures in Mako templates.
bodacydo
@bodacydo: Mako template parsing is *intentionally* a simplification of Python syntax with many, many features discarded. Don't confuse Mako syntax with Python syntax. They're entirely different with entirely different purposes.
S.Lott
If it's good enough for JavaScript, why not Python?
Gabe
I can see a use case for this; in fact, I did it just a couple weeks ago. In my case I wanted an object that I could access attributes with dot notation. I found it very easy to simply inherit from dict so I get all the dict features built-in, but the public interface to this object uses dot notation (it's essentially a read-only interface to some static data). My users are much happier with 'foo.bar' than with 'foo["bar"]' and I'm happy that I can piggy-back off of the features of the dict datatype.
Bryan Oakley
I went with using Bunch from ActiveState http://code.activestate.com/recipes/52308-the-simple-but-handy-collector-of-a-bunch-of-named/This is good enough for now (until I learn good Python style).
bodacydo
@Bryan Oakley: So you built a namedtuple for them? That seems like too much work to me. Why not just create a namedtuple?
S.Lott
@S.Lott: I was using an older version of python that doesn't have namedtuple.
Bryan Oakley
You already know good Python style: we're telling you, don't pretend that the values of a dict are attributes. It's bad practice. For example, what if you want to store a value with the same name as an existing attribute of a dict, like "items" or "get" or "pop"? Probably something confusing. So don't do it!
Larry Hastings
Oops, I forgot about attributes like 'items', 'get' or 'pop. Thanks for bringing up this important example!
bodacydo