[Python-ideas] Keyword only argument on function call

Steven D'Aprano steve at pearwood.info
Thu Sep 6 09:10:28 EDT 2018


On Thu, Sep 06, 2018 at 12:15:46PM +0200, Anders Hovmöller wrote:

> I have a working implementation for a new syntax which would make 
> using keyword arguments a lot nicer. Wouldn't it be awesome if instead 
> of:
> 
> 	foo(a=a, b=b, c=c, d=3, e=e)
> 
> we could just write:
> 
> 	foo(*, a, b, c, d=3, e)
> 
> and it would mean the exact same thing?

No.


> This would not just be shorter but would create an incentive for
> consistent naming across the code base. 

You say that as if consistent naming is *in and of itself* a good thing, 
merely because it is consistent.

I'm in favour of consistent naming when it helps the code, when the 
names are clear and relevant. But why should I feel bad about failing to 
use the same names as the functions I call? If some library author names 
the parameter to a function "a", why should I be encouraged to use 
that same name *just for the sake of consistency*?


> So the idea is to generalize the * keyword only marker from function 
> to also have the same meaning at the call site: everything after * is 
> a kwarg. With this feature we can now simplify keyword arguments 
> making them more readable and concise. (This syntax does not conflict 
> with existing Python code.)

It's certainly more concise, provided those named variables already 
exist, but how often does that happen? You say 30% in your code base.

(By the way, well done for writing an analysis tool! I mean it, I'm not 
being sarcastic. We should have more of those.)

I disagree that f(*, page) is more readable than an explicit named 
keyword argument f(page=page).

My own feeling is that this feature would encourage what I consider a 
code-smell: function calls requiring large numbers of arguments. Your 
argument about being concise makes a certain amount of sense if you are 
frequently making calls like this:

# chosing a real function, not a made-up example
open(file, mode=mode, buffering=buffering, encoding=encoding, 
     errors=errors, newline=newline, closefd=closefd, opener=opener)

If 30% of your function calls look like that, I consider it a 
code-smell.

The benefit is a lot smaller if your function calls look more like this:

open(file, encoding=encoding)

and even less here:

open(file, 'r', encoding=self.encoding or self.default_encoding, 
     errors=self.errors or self.default_error_handler)

for example. To get benefit from your syntax, I would need to 
extract out the arguments into temporary variables:

encoding = self.encoding or self.default_encoding
errors = self.errors or self.default_error_handler
open(file, 'r', *, encoding, errors)

which completely cancels out the "conciseness" argument.

    First version, with in-place arguments:
        1 statement
        2 lines
        120 characters including whitespace

    Second version, with temporary variables:
        3 statements
        3 lines
        138 characters including whitespace


However you look at it, it's longer and less concise if you have to 
create temporary variables to make use of this feature.


-- 
Steve


More information about the Python-ideas mailing list