Currently, Python doesn't allow non-default arguments after default
arguments:
>>> def foo(x=None, y): pass
File "<stdin>", line 1
def foo(x=None, y): pass
^
SyntaxError: non-default argument follows default argument
I believe that at the time this was introduced, no use cases for this
were known and this is is supposed to prevent a source of bugs. I have
two use cases for this, one fringe, but valid, the other more important:
The fringe use case: Suppose you have a function that takes a 2D
coordinate value as separate "x" and "y" arguments. The "x" argument is
optional, the "y" argument isn't. Currently there are two ways to do
this, none of them particularly great:
def foo(y, x): # reverse x and y arguments, confusing
...
def foo(x, y=None): # Treat the x argument as y if only one argument is
provided
if y is None:
x, y = y, x
...
To me, the "natural" solution looks like this:
def foo(x=None, y): ...
# Called like this:
foo(1, 2)
foo(y=2)
This could also be useful when evolving APIs. For example there is a
function "bar" that takes two required arguments. In a later version,
the first argument gains a useful default, the second doesn't. There is
no sensible way to evolve the API at the moment.