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

334 Views Asked by At

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 "".

2

There are 2 best solutions below

3
user3840170 On BEST ANSWER

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.

0
SIGHUP On

How about:

diff = value - (instance.quantity if not isinstance(instance.quantity, type(None)) else Decimal(1000))

...where Decimal(1000) is your default value and the isinstance() test is specific for NoneType (as per the question)