3 ms·
I see the value in the latter for code legibility. My gripe with it is, when I'm new to a project that uses a dict implementation like that: how do I know what
by smoe 9y ago
I see the value in the latter for code legibility. My gripe with it is, when I'm new to a project that uses a dict implementation like that: how do I know what happens if for example `that` is missing? Does it raise AttributeError, KeyError or just return None?
Personally I'd prefer a helper functions like
deep_get(dict_, dotted_path[, default]) -> value
You stil have to check the docs/source what exactly happens, but it is just one simple function instead of magic methods. And i can keep using plain dicts everywhere.
EDIT: To clarify a bit. An experienced Python developer should immediately recognize a call like `deep_get(value,'this.that.the_other')` as something project/framework specific and not built-in, while `value.this.that.the_other` is ambiguous.
- CloudYeller 9y agoYou can get part of the way there with operator.attrgetter: NT = collections.namedtuple('NT', ['x', 'y']) nt1 = NT(1, 2) nt2 = NT(nt1, 'asdf') assert nt2.x.y == 2 get_two = operator.attrgetter('x.y') assert get_two(nt2) == 2 If you wrap the operator.attrgetter in a try/catch, you can force a default too: https://pastebin.com/bFxGr22E https://pastebin.com/bFxGr22E
- smoe 9y agoI never thought much about best implementation because I only used it i think once in ten years. But afaik I used something like this, that does the job and is easy to read _empty = object() def deep_get(dct, dotted_path, default=_empty): for key in dotted_path.split('.'): try: dct = dct[key] except KeyError: if default is _empty: raise return default return dct
- cjhanks 9y agoPersonally I try to implement it as an AttributeError, it seems the most intuitive. By the way, I do understand your point and it's pretty valid in a lot of cases.
- nerdponx 9y agoYou can use `get` from the `toolz` package: toolz.get(value, ['this', 'that', 'the_other'] There's also a Cython implementation called `cytoolz`.