"Safe" operator

A safe operator that allows you to execute code without errors, otherwise return None and break the call chain.

For example:

a = {
    'data': {
        'key1': {
            'key2': {
                ...
            },
        }
    }
}

value = a['data'].get('key1').get('key2')

Suppose we have such a dictionary structure that we get by deserializing the server response. But suppose our keys can be optional. Then, if they are not, then we will get an error.

To avoid doing such a big check:

if 'key1' in a['data'] and 'key2' in a['data']['key1']:

You can use “safe” operator syntax

value = a['data']?.get('key1')?.get('key2')
  1. It returns None if any error is thrown.
  2. Or it can break the call chain if it is applied on a None object.

Where else can this operator be used?

If we take 2 option, then:
For example, instead of this construction:

a = None

if isinstance(a, list):
    a.append(2)

With a “safe” operator it would look like this:

a = None

a?.append(2)

I think this operator will make the code more readable.
What do you think of it?

1 Like

This sounds very much like PEP-505. See the python-ideas archives for previous discussions.

4 Likes

It’s not always as pretty as something you propose but you can use structural pattern matching to replicate this kind of behavior:

match a:
    case {"data": {"key1": {"key2": {...: {"keyN": value}}}}}:
        pass
print(value)
3 Likes

If you got None using the “safer” operator ?., I think you have one problem the reason for getting None is ambiguous. It could be because there is no such key, or the key exists and the value is None.

1 Like

In any case, this frees us from multiple checks for the existence of keys.