Skip to content

Instantly share code, notes, and snippets.

@miku
Last active October 23, 2021 21:16
Show Gist options
  • Save miku/dc6d06ed894bc23dfd5a364b7def5ed8 to your computer and use it in GitHub Desktop.
Save miku/dc6d06ed894bc23dfd5a364b7def5ed8 to your computer and use it in GitHub Desktop.
https://stackoverflow.com/a/23689767/89391 / How to use a dot “.” to access members of dictionary?
class dotdict(dict):
"""
A dictionary supporting dot notation.
"""
__getattr__ = dict.get
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for k, v in self.items():
if isinstance(v, dict):
self[k] = dotdict(v)
def lookup(self, dotkey):
"""
Lookup value in a nested structure with a single key, e.g. "a.b.c"
"""
path = list(reversed(dotkey.split(".")))
v = self
while path:
key = path.pop()
if isinstance(v, dict):
v = v[key]
elif isinstance(v, list):
v = v[int(key)]
else:
raise KeyError(key)
return v
if __name__ == '__main__':
dd = dotdict({"a": 1, "b": {"c": "# it works", "d": [1, 2, {"e": 123}]}})
print(dd.b.c)
print("#", isinstance(dd, dict))
print("#", dd.lookup("b.d"))
# it works
# True
# [1, 2, {'e': 123}]
from collections import defaultdict
class AttributeDict(defaultdict):
def __init__(self):
super(AttributeDict, self).__init__(AttributeDict)
def __getattr__(self, key):
try:
return self[key]
except KeyError:
raise AttributeError(key)
def __setattr__(self, key, value):
self[key] = value
if __name__ == '__main__':
print(AttributeDict({"a": 1, "b": {"c": "# it works"}}).b.c)
# Traceback (most recent call last):
# File "41274937.py", line 18, in <module>
# print(AttributeDict({"a": 1, "b": {"c": "# it works"}}).b.c)
# TypeError: __init__() takes 1 positional argument but 2 were given
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment