Attribute Access with Dict
Python dict
is useful. The access to a nested item can be tedious, however. For example,
data = {
"hosts": {
"name": "localhost",
"cidr": "127.0.0.1/8",
}
}
Here, data["hosts"]["cidir"]
would get you "127.0.0.1/8"
, but all those quotes and brackets can be annoying to type and read. A singly nested dict
like the case above is not bad, but this can quickly become tedium as the nesting deepens. It would be so much more succinct to be able to access an item at a key through attributes, as in data.hosts.cidir
.
Such attribute access is fairly simple to implement using the __dict__
magic attribute Python uses to define object attributes:
from collections import UserDict
class AttrDict(UserDict):
pass
def attrdict(d: dict) -> AttrDict:
def addattrs(d):
if not isinstance(d, dict):
return d
obj = AttrDict()
for k in d:
obj[k] = obj.__dict__[k] = addattrs(d[k])
return obj
obj = AttrDict()
obj.update(d)
obj.__dict__.update(addattrs(d))
return obj
There are caveats. If a key in the input dict
contains invalid characters for an attribute name (e.g., space), the item for the key will not be accessible as an attribute (though it remains accessible through an index). Keys also need to be str
, whereas dict
keys in general can be any hashable Python object. More importantly, if any key in the input dict
conflicts with the method or attribute names of the dict
interface, the object may not function properly as dict
anymore.
So long as the limitations are understood, a solution like this can be good enough in some cases, simple JSON objects with well-defined structure, for example.