Search code examples
pythonnull-coalescing

Is there a nice one-liner to provide a default if a value is None?


There is a possibility that I am searching under wrong keywords, but I can't find the answer to the question:

Is there a nice one-liner to provide a default value if the variable is NoneType?

For example:

def validate_quantity(self, value):
        instance = self.instance
        diff = value - instance.quantity

results in error:

unsupported operand type(s) for -: 'decimal.Decimal' and 'NoneType'

I know dictionaries have a .get() method which works like that:

smth.get('quantity', 200)

but it cannot be applied to an object instance.

This:

diff = value - (instance.quantity or 0)

does not work either because it returns 0 when instance.quantity is None, but also when it is [] or "".


Solution

  • Using the walrus operator, introduced in Python 3.8 (PEP 572):

    diff = value - (0 if (q := instance.quantity) is None else q)
    

    To me, it looks at best moderately readable (you can also try swapping ‘then’ and ‘else’ parts, i.e. q if (q := instance.quantity) is not None else 0, if you prefer), but it has the advantage that it only evaluates instance.quantity once, and does not evaluate the fallback expression if not needed.

    There have been proposals to introduce a proper None-coalescing operator (see PEP 505), but there is currently no consensus to add one to the language. The LWN article ‘Not coalescing around None-aware’ covers some discussions.