Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

248
Views
Why can't the args and keyword only arguments be mixed with *args and **kwargs simultaneously?

I would like to understand is: why is it not possible to simultaneously define mandatory positional arguments, mandatory kwarg arguments and eventually allow capturing other arguments and kwargs as cant_do_that below?

 def one_kwarg_is_mandatory(*, b, **kwargs): print(b) for key, value in kwargs.items(): print(key, value) def one_pos_arg_and_one_kwarg_are_mandatory(a, *, b, **kwargs): print(a, b) for key, value in kwargs.items(): print(key, value) # I wanted a mandatory arg (a) and possibly parse other args (*args), # then a mandatory kwarg (b) and eventually other kwargs (**kwargs) def cant_do_that(a, *args, *, b, **kwargs): print(a, b) print(args) for key, value in kwargs.items(): print(key, value) # not really interested on this because "b" must be a kwarg and hiding # it under **kwargs would not be explicit enough for my customer (sometimes myself ;)) def could_do_this_but(a, b, *args, **kwargs): print(a, b) print(args) print(kwargs)

Yes, one could get rid of b signature in the could_do_this_but function, perform (say) a kwargs.get("b", None) at the top of the function, and raise some appropriate error if None is encountered ... but having "b" directly in the function signature would allow faster and more explicit code development using the function on the fly.

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

The correct syntax is def cant_do_that(a, *args, b, **kwargs): . Note that * is used only once, both to mark the end of positional arguments and to set the name of variadic positional arguments.


The * definition in a function is syntactically unique in the separation between positional or keyword and keyword-only arguments:

 parameter_list_starargs ::= "*" [parameter] ("," defparameter)* ["," ["**" parameter [","]]] | "**" parameter [","]

"*" [parameter] In short, the grammatical means * and *args are syntactically the same thing, a literal name * and optional, which can occur only once. Use a bare * to start keyword-only arguments without taking mixed positional arguments, and use a named *args to start keyword-only arguments taking mixed positional arguments.

If the form “ *identifier ” is present, it is initialized to a tuple that receives any excess positional parameters, defaulting to the empty tuple. [...] Parameters after " * " or " *identifier " are keyword-only parameters and only used keyword arguments can be passed.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!