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?
- 14Once you get a grasp on these, you'll never want to miss them (especially, if you ever had to deal with PHP's
func_*_args()).Boldewyn– Boldewyn2010-08-03 09:43:26 +00:00CommentedAug 3, 2010 at 9:43 - 5The docs are atdocs.python.org/faq/programming.html#id13, btw.mlvljr– mlvljr2011-05-24 16:34:58 +00:00CommentedMay 24, 2011 at 16:34
- 3Actually, these 2 argument formats can be added to any function declaration as long as they are the last 2. Note the order:
explicit args, then *args, then **kwargs. e.g.def foo (arg1, arg2, *args, **kwargs): ...smwikipedia– smwikipedia2016-01-11 04:10:51 +00:00CommentedJan 11, 2016 at 4:10 - (If you are in Javascript there's
argumentsarray that's similar)NoBugs– NoBugs2018-01-08 04:39:00 +00:00CommentedJan 8, 2018 at 4:39 - In some other languages the
*argsform would be known as variadic arguments.Mark Ransom– Mark Ransom2023-03-22 12:17:12 +00:00CommentedMar 22, 2023 at 12:17
11 Answers11
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:
>>> def print_everything(*args): for count, thing in enumerate(args):... print( '{0}. {1}'.format(count, thing))...>>> print_everything('apple', 'banana', 'cabbage')0. apple1. banana2. cabbageSimilarly,**kwargs allows you to handle named arguments that you have not defined in advance:
>>> def table_things(**kwargs):... for name, value in kwargs.items():... print( '{0} = {1}'.format(name, value))...>>> table_things(apple = 'fruit', cabbage = 'vegetable')cabbage = vegetableapple = fruitYou 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:
def table_things(titlestring, **kwargs)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:
>>> def print_three_things(a, b, c):... print( 'a = {0}, b = {1}, c = {2}'.format(a,b,c))...>>> mylist = ['aardvark', 'baboon', 'cat']>>> print_three_things(*mylist)a = aardvark, b = baboon, c = catAs 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.
9 Comments
function_call(arg1,arg2,*expanded_list_args,arg4,arg5). The expanded list may only be followed by keyword arguments I believe. Is there a way to get around that?a, b, *c, d, e = 1, 2, 3, 4, 5, 6 assigns c to [3, 4]. A bit confusingmylist is likean array in JS. Our normal method ofprint_three_things takes 3 args. Passing it to print_three_things(*mylist), the* annotation is more or less like thespreading operator in ES6. Let me know if my consideration is okay or wrong? ThanksOne place where the use of*args and**kwargs is quite useful is for subclassing.
class Foo(object): def __init__(self, value1, value2): # do something with the values print value1, value2class MyFoo(Foo): def __init__(self, *args, **kwargs): # do something else, don't care about the args print 'myfoo' super(MyFoo, self).__init__(*args, **kwargs)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.
12 Comments
value2 goes as first element inargs, so no exception.Here's an example that uses 3 different types of parameters.
def func(required_arg, *args, **kwargs): # required_arg is a positional-only parameter. print required_arg # args is a tuple of positional arguments, # because the parameter name has * prepended. if args: # If args is not empty. print args # kwargs is a dictionary of keyword arguments, # because the parameter name has ** prepended. if kwargs: # If kwargs is not empty. print kwargs>>> func()Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: func() takes at least 1 argument (0 given)>>> func("required argument")required argument>>> func("required argument", 1, 2, '3')required argument(1, 2, '3')>>> func("required argument", 1, 2, '3', keyword1=4, keyword2="foo")required argument(1, 2, '3'){'keyword2': 'foo', 'keyword1': 4}Comments
Here's one of my favorite places to use the** syntax as in Dave Webb's final example:
mynum = 1000mystr = 'Hello World!'print("{mystr} New-style formatting is {mynum}x more fun!".format(**locals()))I'm not sure if it's terribly fast when compared to just using the names themselves, but it's a lot easier to type!
8 Comments
format method already exist even in Python 2?f'{mystr} New-style formatting is {mynum}x more fun!')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:
def mydecorator( f ): @functools.wraps( f ) def wrapper( *args, **kwargs ): print "Calling f", args, kwargs v = f( *args, **kwargs ) print "f returned", v return v return wrapperComments
*args and **kwargs are special-magic features of Python.Think of a function that could have an unknown number of arguments. For example, for whatever reasons, you want to have function that sums an unknown number of numbers (and you don't want to use the built-in sum function). So you write this function:
def sumFunction(*args): result = 0 for x in args: result += x return resultand use it like: sumFunction(3,4,6,3,6,8,9).
**kwargs has a diffrent function. With **kwargs you can give arbitrary keyword arguments to a function and you can access them as a dictonary.
def someFunction(**kwargs): if 'text' in kwargs: print kwargs['text']Calling someFunction(text="foo") will print foo.
1 Comment
*args and**kwargs XD. Thank you sir.Just imagine you have a function but you don't want to restrict the number of parameter it takes.Example:
>>> import operator>>> def multiply(*args):... return reduce(operator.mul, args)Then you use this function like:
>>> multiply(1,2,3)6or>>> numbers = [1,2,3]>>> multiply(*numbers)6Comments
The names*args and**kwargs or**kw are purely by convention. It makes it easier for us to read each other's code
One 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.
tuple_of_data = struct.unpack(format_str, data)# ... manipulate the datanew_data = struct.pack(format_str, *tuple_of_data)without this ability you would be forced to write
new_data = struct.pack(format_str, tuple_of_data[0], tuple_of_data[1], tuple_of_data[2],...)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
Comments
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:
def myprint(*args): print *argsUnfortunately it doesn't compile (syntax error).
This compiles:
def myprint(*args): print argsBut prints the arguments as a tuple, which isn't what we want.
This is the solution I settled on:
def myprint(*args): for arg in args: print arg, print2 Comments
from __future__ import print_function :)These parameters are typically used for proxy functions, so the proxy can pass any input parameter to the target function.
def foo(bar=2, baz=5): print bar, bazdef proxy(x, *args, **kwargs): # reqire parameter x and accept any number of additional arguments print x foo(*args, **kwargs) # applies the "non-x" parameter to fooproxy(23, 5, baz='foo') # calls foo with bar=5 and baz=fooproxy(6)# calls foo with its default argumentsproxy(7, bar='asdas') # calls foo with bar='asdas' and leave baz default argumentBut since these parameters hide the actual parameter names, it is better to avoid them.
Comments
You can have a look at python docs (docs.python.org in the FAQ), but more specifically for a good explanationthe mysterious miss args and mister kwargs (courtesy of archive.org) (the original, dead link ishere).
In a nutshell, both are used when optional parameters to a function or method are used. As Dave says, *args is used when you don't know how many arguments may be passed, and **kwargs when you want to handle parameters specified by name and value as in:
myfunction(myarg=1)2 Comments
**kwargs is required to use named arguments, which is false. It's only needed to handlearbitrary named arguments.Explore related questions
See similar questions with these tags.









