[Python-Dev] PEP 3102: Keyword-only arguments

Georg Brandl g.brandl at gmx.net
Sun Apr 30 19:47:35 CEST 2006


Zachary Pincus wrote:
> Some thoughts from a lurker, largely concerning syntax; discount as  
> you wish.
> 
> First:
>>      Keyword-only arguments are not required to have a default value.
>>      Since Python requires that all arguments be bound to a value,
>>      and since the only way to bind a value to a keyword-only argument
>>      is via keyword, such arguments are therefore 'required keyword'
>>      arguments.  Such arguments must be supplied by the caller, and
>>      they must be supplied via keyword.
> 
> So what would this look like?
>    def foo(*args, kw1, kw2):
> 
> That seems a bit odd, as my natural expectation wouldn't be to see  
> kw1 ands kw2 as required, no-default keyword args, but as misplaced  
> positional args.
> 
> Perhaps this might be a little better?
>    def foo(*args, kw1=, kw2=):
> I'm rather not sure. At least it makes it clear that kw1 and kw2 are  
> keyword arguments, and that they have no default values.

Interesting, but perhaps a little too fancy.

> Though, I'm kind of neutral on the whole bit -- in my mind "keyword  
> args" and "default-value args" are pretty conflated and I can't think  
> of any compelling reasons why they shouldn't be. It's visually handy  
> when looking at some code to see keywords and be able to say "ok,  
> those are the optional args for changing the handling of the main  
> args". I'm not sure where the big win with required keyword args is.

Personally I think that required keyword args will not be the most used
feature brought by this PEP. More important is that you can give a function
as many positional args as you want, all sucked up by the *args, and still
supply a "controlling" keyword arg.

> For that matter, why not "default positional args"? I think everyone  
> will agree that seems a bit odd, but it isn't too much odder than  
> "required keyword args". (Not that I'm for the former! I'm just  
> pointing out that if the latter is OK, there's no huge reason why the  
> former wouldn't be, and that is in my mind a flaw.)
> 
> Second:
>>   def compare(a, b, *, key=None):
> This syntax seems a bit odd to me, as well. I always "understood" the  
> *args syntax by analogy to globbing -- the asterisk means to "take  
> all the rest", in some sense in both a shell glob and *args.
> 
> In this syntax, the asterisk, though given a position in the comma- 
> separated list, doesn't mean "take the rest and put it in this  
> position." It means "stop taking things before this position", which  
> is a bit odd, in terms of items *in* an argument list.

It continues to mean "take the rest", but because there is no name to
put it into, it will raise an exception if a rest is present.
For me, it seems consistent.

> I grant that it makes sense as a derivation from "*ignore"-type  
> solutions, but as a standalone syntax it feels off. How about  
> something like:
>    def compare(a, b; key=None):
> 
> The semicolon is sort of like a comma but more forceful; it ends a  
> phrase. This seems like a logical (and easily comprehended by  
> analogy) use here -- ending the "positional arguments" phrase.

Guido already ruled it out because it's an "end of statement" marker
and nothing else.

Georg



More information about the Python-Dev mailing list