Last active
October 23, 2021 21:16
-
-
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?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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}] | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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