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.
- It’s extra typing.
- It’s error-prone. The above expression cannot be
x is None and something or x
becausesomething
might be falsey and the expression would evaluate tosomething
instead ofx
- 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