Python function call with * args, ** kwargs and optional / default arguments

In python, I can define a function as follows:

def func(kw1=None,kw2=None,**kwargs): ... 

In this case, I can call func like:

 func(kw1=3,kw2=4,who_knows_if_this_will_be_used=7,more_kwargs=Ellipsis) 

I can also define the function as:

 def func(arg1,arg2,*args): ... 

which can be called

 func(3,4,additional,arguments,go,here,Ellipsis) 

Finally, I can combine the two forms

 def func(arg1,arg2,*args,**kwargs): ... 

But what does not work causes:

 func(arg1,arg2,*args,kw1=None,kw2=None,**kwargs): #SYNTAX ERROR (in python 2 only, apparently this works in python 3) ... 

My initial thought was that it was probably because the function

 def func(arg1,arg2,*args,kw1=None): ... 

can be called

 func(1,2,3) #kw1 will be assigned 3 

Thus, this will lead to some ambiguity as to whether 3 should be packed in args or kwargs. However, with python 3, you can only specify keyword arguments:

 def func(a,b,*,kw=None): #can be called as func(1,2), func(1,2,kw=3), but NOT func(1,2,3) ... 

With this, there seems to be no syntactic ambiguity with:

 def func(a,b,*args,*,kw1=None,**kwargs): ... 

However, this still causes a syntax error (verified with Python3.2). Is there a reason for this that I am missing? And is there any way to get the behavior described above (having arguments with default arguments). I know that I can simulate this behavior by manipulating the kwargs dictionary inside a function.

+55
python syntax kwargs
Mar 26 2018-12-12T00:
source share
2 answers

You can do this in Python 3.

 def func(a,b,*args,kw1=None,**kwargs): 

Naked * is only used if you want to specify arguments for keywords only, without accepting a variable number of positional arguments with *args . You are not using two * s.

To quote the grammar, in Python 2 you have

 parameter_list ::= (defparameter ",")* ( "*" identifier [, "**" identifier] | "**" identifier | defparameter [","] ) 

while in python 3 you have

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

which includes the position for additional parameters after parameter * .

UPDATE:

The latest Python 3 documentation is here .

+57
Mar 26 2018-12-12T00:
source share

If you want to make a mixture of both, remember that * args and ** kwargs must be the last parameters specified.

 def func(arg1,arg2,*args,kw1=None,kw2=None,**kwargs): #Invalid def func(arg1,arg2,kw1=None,kw2=None,*args,**kwargs): #Valid 

The comments seem to be based on a mixture of how the definition of the function is constructed compared to how the arguments provided are assigned to the parameters specified in the definition.

This is the definition of this function, which has 6 parameters. It is called by passing named and unnamed arguments to a function call.

For this example ... When an argument is named when a function is called, it can be provided out of order. arg1 and arg2 are required parameters, and if they are not passed to the function as named arguments, then they must be assigned in order from the nameless arguments provided. The values โ€‹โ€‹of kw1 and kw2 have the default values โ€‹โ€‹specified in the function definition, therefore they are optional, but if they are not specified as named arguments, they will take any available values โ€‹โ€‹from the remaining nameless arguments provided. Any remaining nameless arguments are provided to the function in an array named args. Any named arguments that do not have a matching parameter name in the function definition are provided to the function call in a dictionary named kwargs.

+6
Sep 22 '13 at 0:12
source share



All Articles