Built-in "default value" function, like NVL(x, y) in SQL

I have a function def f(x = None): ... In that function, I want to compute a default value for x as something if x is None else x. Or possibly have a statement like if x is None: x = something
There are three disadvantages to this.

  1. It’s extra typing.
  2. It’s error-prone. The above expression cannot be x is None and something or x because something might be falsey and the expression would evaluate to something instead of x
  3. It is slower since it calls the interpreter for this expression.

I would like to have a built-in function called, say, default_value. Its definition is

def default_value(value: Any, default: Any, sentinel: Any = None) -> Any:

    return default if value == sentinel else value

Inside my f function, I would call default_value(x, something).

There are many situations where None is a legitimate value for the argument, and a singleton value must be the default. In that case, I would have

SENTINEL = object()
def f(x = SENTINEL):
    ...
    x = default_value(x, something, SENTINEL)
    ...

Calling default_value() makes the code more concise and clear, as it states exactly what is being computed.

Now it may be argued that if something takes time to compute, or suffer some other failure when it’s not needed, one does not want to use default_value(). So the documentation should suggest that the default argument should be an expression which does require (much) computation, such as a variable name or a constant value.

I suspect that there are lots of functions in the standard library and in contributed libraries,where None or some sentinel is used as a default value and an actual value is computed. These could be improved in performance by using default_value(). I don’t know if you people have tools which can scan code looking for various patterns, but if you do, then you can get an idea of how often this occurs.

Of course, for the average Python programmer, I think that default_value would be a useful feature.

By the way, the SQL function NVL (x, y) evaluates to y ix x is NULL and to x otherwise. See NVL.

Follow-up

I personally do not intend to watch for comments on this idea, so I will not be the one to file a feature issue with cpython. Someone who is reading this post will have to take the initiative to file the Issue and eventually submit a PEP.

Thanks for reading this and for your comments.

Michael Rolle

This someone should also actually do research before continuing this discussion, reading back on the gigantic amount of previous suggested idea around:

  • builtin sentinel factory
  • deferred expressions
  • late-bound default arguments
  • None-aware operators
  • if/else/and/or operator overloading

I don’t believe there is much value in starting another discussion with a half-baked idea as it’s bases.

5 Likes