This question already has an answer here:
So I have difficulty with the concept of *args
and **kwargs
.
So far I have learned that:
*args
= list of arguments - as positional arguments**kwargs
= dictionary - whose keys become separate keyword arguments and the values become values of these arguments.
I don't understand what programming task this would be helpful for.
Maybe:
I think to enter lists and dictionaries as arguments of a function AND at the same time as a wildcard, so I can pass ANY argument?
Is there a simple example to explain how *args
and **kwargs
are used?
Also the tutorial I found used just the "*" and a variable name.
Are *args
and **kwargs
just placeholders or do you use exactly *args
and **kwargs
in the code?
Just imagine you have a function but you don't want to restrict the number of parameter it takes. Example:
Then you use this function like:
One place where the use of
*args
and**kwargs
is quite useful is for subclassing.This way you can extend the behaviour of the Foo class, without having to know too much about Foo. This can be quite convenient if you are programming to an API which might change. MyFoo just passes all arguments to the Foo class.
The names
*args
and**kwargs
or**kw
are purely by convention. It makes it easier for us to read each other's codeOne place it is handy is when using the struct module
struct.unpack()
returns a tuple whereasstruct.pack()
uses a variable number of arguments. When manipulating data it is convenient to be able to pass a tuple tostruck.pack()
eg.without this ability you would be forced to write
which also means the if the format_str changes and the size of the tuple changes, I'll have to go back and edit that really long line
Note that *args/**kwargs is part of function-calling syntax, and not really an operator. This has a particular side effect that I ran into, which is that you can't use *args expansion with the print statement, since print is not a function.
This seems reasonable:
Unfortunately it doesn't compile (syntax error).
This compiles:
But prints the arguments as a tuple, which isn't what we want.
This is the solution I settled on:
One case where *args and **kwargs are useful is when writing wrapper functions (such as decorators) that need to be able accept arbitrary arguments to pass through to the function being wrapped. For example, a simple decorator that prints the arguments and return value of the function being wrapped:
The syntax is the
*
and**
. The names*args
and**kwargs
are only by convention but there's no hard requirement to use them.You would use
*args
when you're not sure how many arguments might be passed to your function, i.e. it allows you pass an arbitrary number of arguments to your function. For example:Similarly,
**kwargs
allows you to handle named arguments that you have not defined in advance:You can use these along with named arguments too. The explicit arguments get values first and then everything else is passed to
*args
and**kwargs
. The named arguments come first in the list. For example:You can also use both in the same function definition but
*args
must occur before**kwargs
.You can also use the
*
and**
syntax when calling a function. For example:As you can see in this case it takes the list (or tuple) of items and unpacks it. By this it matches them to the arguments in the function. Of course, you could have a
*
both in the function definition and in the function call.