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 actually 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 attribute name (e.g., space), the item for the key will
not be accessible as an attribute (though it remains accessible
through 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
any more.
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.