[Python-ideas] keyword arguments everywhere (stdlib) (original) (raw)

Guido van Rossum guido at python.org
Sat Mar 3 04:31:06 CET 2012


On Fri, Mar 2, 2012 at 6:57 PM, Steven D'Aprano <steve at pearwood.info> wrote:

I believe that the right place to tag the parameter is in the parameter itself, not by adding an extra parameter after it. Hence, something like this:

def spam(~x, ~y, ~z, ~a=2/3):  ... where ~name means that name cannot be specified by keyword. I read it as "not name", as in, the caller can't use the name. Or if you prefer Guido's pun: def spam(/x, /y, /z, /a=2/3):  ... Much less line-noise than spam(x, /, y, /, z, /, a=2/3, /).

That can't be right -- if a parameter is positional, surely all parameters before it are also positional, so it would be redundant to have to mark all of them up. Also ~name looks too much like an expression and /name looks just weird (I think DOS command line flags used to look like this).

Personally, I think this is somewhat of an anti-feature. Keyword arguments are a Good Thing, and while I don't believe it is good enough to force all C functions to support them, I certainly don't want to discourage Python functions from supporting them.

And yet people invent decorators and other hacks to insist on positional parameters all the time. You can have Too Much of a Good Thing, and for readability it's better if calls are consistent. If most calls to a function use positional arguments (at least for the first N positions), it's better to force all calls to use positional arguments 1-N: the reader may be unfamiliar with the parameter names. Also remember the subclassing issue I brought up before.

That said, I can't come up with a syntax that I really like. Here's my best attempt, but I'm at most -0 on it: Have a stand-alone '/' indicate "all parameters to my left must be positional", just like a stand-alone '' means "all parameters to my right must be keywords". If there's no stand-alone '' it is assumed to be all the way on the right; so if there's no '/' it is assumed to be all the way on the left. The following should all be valid:

def foo(/, a, b): ... # edge case, same as def foo(a, b): ...

def foo(a, b, /): ... # all positional

def foo(a, b=1, /): ... # all positional, b optional

def foo(a, b, /, c, d): ... # a, b positional; c, d required and either positional or keyword

def foo(a, b, /, c, d=1): ... # a, b positional; c required, d optional; c, d either positional or keyword

def foo(a, b, /, c, *, d): ... # a, b positional; c required and either positional or keyword; d required keyword

def foo(a, b=1, /, c=1, *, d=1): ... # same, but b, c, d optional

That about covers it. But agreed it's no thing of beauty, so let's abandon it.

-- --Guido van Rossum (python.org/~guido)



More information about the Python-ideas mailing list