I find it more conveniant to access dict keys as obj.foo
instead of obj['foo']
, so I wrote this snippet:
class AttributeDict(dict):
def __getattr__(self, attr):
return self[attr]
def __setattr__(self, attr, value):
self[attr] = value
However, I assume there must be some reason that Python doesn't provide this functionality out of the box. What would be the caveats and pitfalls of accessing dict keys in this manner?
Solution is:
You can have all legal string characters as part of the key if you use array notation. For example,
obj['!#$%^&*()_']
tuples can be used dict keys. How would you access tuple in your construct?
Also, namedtuple is a convenient structure which can provide values via the attribute access.
Here's a short example of immutable records using built-in
collections.namedtuple
:and a usage example:
Apparently there is now a library for this - https://pypi.python.org/pypi/attrdict - which implements this exact functionality plus recursive merging and json loading. Might be worth a look.
The best way to do this is:
Some pros:
.keys()
work just fine)AttributeError
instead ofKeyError
Cons:
.keys()
will not work just fine if they get overwritten by incoming dataE1123(unexpected-keyword-arg)
andE1103(maybe-no-member)
A short explanation on how this works
__dict__
.__dict__
would need to be "just a plain dict", so we can assign any subclass ofdict()
to the internal dictionary.AttrDict()
instance we are instantiating (as we are in__init__
).super()
's__init__()
method we made sure that it (already) behaves exactly like a dictionary, since that function calls all the dictionary instantiation code.One reason why Python doesn't provide this functionality out of the box
As noted in the "cons" list, this combines the namespace of stored keys (which may come from arbitrary and/or untrusted data!) with the namespace of builtin dict method attributes. For example: