Source code for dolor.util.attr_dict

"""Contains :class:`~.AttrDict`"""

import collections

[docs]class AttrDict(collections.abc.MutableMapping): """A wrapper around :class:`dict` that also lets you access keys as attributes. Parameters ---------- name_or_elems : :class:`str` or :class:`dict`, optional If a :class:`str`, then it will generate a new type with that name that inherits from :class:`AttrDict`. If a :class:`dict`, then it will use it as its underlying dictionary. If unspecified, then the initial underlying dictionary will be empty. **kwargs Will be used with :meth:`dict.update` to update the underlying dictionary. Examples -------- >>> import dolor >>> MyAttrDict = dolor.util.AttrDict("MyAttrDict") >>> MyAttrDict.__name__ 'MyAttrDict' >>> x = MyAttrDict(y=0) >>> x.y 0 >>> x["y"] 0 """ def __new__(cls, name_or_elems=None, **kwargs): if not isinstance(name_or_elems, str): return super().__new__(cls) return type(name_or_elems, (cls,), {}) def __init__(self, elems=None, **kwargs): if elems is None: elems = {} elems.update(kwargs) self._elems = elems def __getitem__(self, key): return self._elems[key] def __setitem__(self, key, value): self._elems[key] = value def __delitem__(self, key): del self._elems[key] def __len__(self): return len(self._elems) def __iter__(self): return self._elems.__iter__() def __getattr__(self, attr): try: return self._elems[attr] except KeyError: raise AttributeError def __setattr__(self, attr, value): if attr == "_elems": super().__setattr__(attr, value) return self._elems[attr] = value def __delattr__(self, attr): if attr == "_elems": super().__delattr__(attr) return del self._elems[attr] def __repr__(self): return f"{type(self).__name__}({self._elems})"