On Tue, Nov 9, 2021 at 8:38 PM Sebastian Rittau <srit...@rittau.biz> wrote: > > 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. >
What would this mean, though: foo(2) Is that legal? If it is, it has to be the same as foo(y=2), by your definition. But that would mean that it's hard to get your head around the mapping of arguments and parameters. foo(1, 2) # x=1, y=2 foo(1) # x=None, y=1 There are a very very few functions in Python that have this sort of odd behaviour (range() being probably the only one most programmers will ever come across), and it's not something to encourage. I would instead recommend making the parameters keyword-only, which would allow any of them to have defaults or not have defaults. In terms of useful API design, this is usually more helpful than having an early parameter omitted. ChrisA _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/5DPSPZFJBAIWS4UARIJYRCLNVUIUFKWD/ Code of Conduct: http://python.org/psf/codeofconduct/