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?
How about Prodict, the little Python class that I wrote to rule them all:)
Plus, you get auto code completion, recursive object instantiations and auto type conversion!
You can do exactly what you asked for:
Example 1: Type hinting
Example 2: Auto type conversion
This isn't a 'good' answer, but I thought this was nifty (it doesn't handle nested dicts in current form). Simply wrap your dict in a function:
Now you have slightly different syntax. To acces the dict items as attributes do
f.key
. To access the dict items (and other dict methods) in the usual manner dof()['key']
and we can conveniently update the dict by calling f with keyword arguments and/or a dictionaryExample
And there it is. I'll be happy if anyone suggests benefits and drawbacks of this method.
As @Henry suggests, one reason dotted-access may not be used in dicts is that it limits dict key names to python-valid variables, thereby restricting all possible names.
The following are examples on why dotted-access would not be helpful in general, given a dict,
d
:Validity
The following attributes would be invalid in Python:
Style
PEP8 conventions would impose a soft constraint on attribute naming:
A. Reserved keyword (or builtin function) names:
B. The case rule on methods and variable names:
Sometimes these concerns are raised in libraries like pandas, which permits dotted-access of DataFrame columns by name. The default mechanism to resolve naming restrictions is also array-notation - a string within brackets.
If these constraints do not apply to your use case, there are several options on dotted-access data structures.
Just to add some variety to the answer, sci-kit learn has this implemented as a
Bunch
:All you need is to get the
setattr
andgetattr
methods - thegetattr
checks for dict keys and the moves on to checking for actual attributes. Thesetstaet
is a fix for fix for pickling/unpickling "bunches" - if inerested check https://github.com/scikit-learn/scikit-learn/issues/6196