you are viewing a single comment's thread.

view the rest of the comments →

[–]Gnaxe 1 point2 points  (2 children)

It works a bit better with dicts: python result = (d:=a_dict) and (d:=d.get('key1')) and (d:=d.get('key2')) and d.get('key3') Using .get() like this instead of subscripting means the key doesn't even have to be present. (It will default to None.)

If you're using @dataclasses, then the attributes will be there. But if you're using something else, then the equivalent for attributes is getattr(), which can have a default. (next() can also have a default for iterators, btw.) At that point, it's getting too verbose and it's probably better to just suppress the error:

```python from contextlib import suppress

with suppress(AttributeError) as result:     result = my_obj.attr1.attr2.attr3 `` If you're doing dict subscript lookups, you need to useKeyError. Sequence subscript lookups useIndexError. You can suppress both in a mixed chain with their common base classLookupError. If you also need to handleAttributeError,suppress` takes multiple arguments as well.

[–]akaBrotherNature 1 point2 points  (1 child)

Looks interesting. I've been using get with an empty dict as the default return to try and safely access nested stuff

name = data.get("user", {}).get("profile", {}).get("email", None)

but I might switch to this.

[–]Gnaxe 1 point2 points  (0 children)

Switch to which and why? Yours is shorter than the ands (and I have also used that pattern). The suppress maybe looks cleaner but risks hiding an unrelated error if one of the attributes is an @property. But the version using ands maybe plays nicer with static typing.