How to use *args and **kwargs in Python
Or, How to use variable length argument lists in Python.
The special syntax, *args
and **kwargs
in function definitions is used to pass a variable number of arguments to a function. The single asterisk form (*args
) is used to pass a non-keyworded, variable-length argument list, and the double asterisk form is used to pass a keyworded, variable-length argument list. Here is an example of how to use the non-keyworded form. This example passes one formal (positional) argument, and two more variable length arguments.
def test_var_args(farg, *args):
print "formal arg:", farg
for arg in args:
print "another arg:", arg
test_var_args(1, "two", 3)
Results:
formal arg: 1 another arg: two another arg: 3
Here is an example of how to use the keyworded form. Again, one formal argument and two keyworded variable arguments are passed.
def test_var_kwargs(farg, **kwargs):
print "formal arg:", farg
for key in kwargs:
print "another keyword arg: %s: %s" % (key, kwargs[key])
test_var_kwargs(farg=1, myarg2="two", myarg3=3)
Results:
formal arg: 1 another keyword arg: myarg2: two another keyword arg: myarg3: 3
Using *args
and **kwargs
when calling a function¶
This special syntax can be used, not only in function definitions, but also when calling a function.
def test_var_args_call(arg1, arg2, arg3):
print "arg1:", arg1
print "arg2:", arg2
print "arg3:", arg3
args = ("two", 3)
test_var_args_call(1, *args)
Results:
arg1: 1 arg2: two arg3: 3
Here is an example using the keyworded form when calling a function:
def test_var_args_call(arg1, arg2, arg3):
print "arg1:", arg1
print "arg2:", arg2
print "arg3:", arg3
kwargs = {"arg3": 3, "arg2": "two"}
test_var_args_call(1, **kwargs)
Results:
arg1: 1 arg2: two arg3: 3
See also (updated 2009-04-12)
- Section 4.7 More on Defining Functions in the Official Python Tutorial
- PEP 3102 Keyword-Only Arguments
- Section 5.3.4 Calls in the Python Reference Manual
Reference: Core Python Programming, Second Edition, Section 11.6
Comments
Thanks for the succinct explanation of args and *kwargs. You made it nice and easy to understand.
thanks for this explanation. It's pretty cool to have such informations easy to understand.
Thanks for your explanation.
Thanks just learnt python from Think Python free book, but there was no mention of this. I was seeing it frequently in other peoples code and it was confusing me. Not now. Thanks again!
Mike, I had not heard of Think Python. It looks like a great free Python resource.
Awesome! This is THE explanation I was looking for :).
I have newly discovered your blog and it is awsome. Also this is a very good tip. Thanks you!
I too want to thank you for your explanation. Just started Python/Django and blogs like this really speed up the task.
Excellent explanation, no wonder it's the first google-hit for 'kwargs'. You might mention that the terms 'args' and 'kwargs' are arbitrary, though. I found out later that you can use any non-keyword identifier, as long as you use the asterisks.
Protector one, you make a good point, the terms "args" and "kwargs" are arbitrary. thank you. i'll try to add a note in the post when i get a chance.
Excellent, clear explanation. Thanks for the post.
Thanks a lot! I have a question:
Here is a function: def myfunction(self, a=None, b=None): pass
Is it possible to make sure that the user will call the function like this:
self.myfunction(a=2, b=3)
self.myfunction(a=2)
self.myfunction(b=3),
and that he won't be able to call the function without specifying which number is which parameter. I don't want this: self.myfunction(2, 3)
self.myfunction(2)
Emma
Emma, That's a good question-- I don't know the answer. If you find the answer, let me know.
Pretty usefull stuff. I found it usefull for my hobby project.
Python is so cool. :-)
For Emma
if you define your function like this:
def myfunction(self,**kwargs):pass
then u can call it like this:
self.myfunction()
self.myfunction(a=1)
self.myfunction(a=1,b=2)
self.myfunction(a=1,b=2,c=3)
....
if called like self.myfunction(1,2)
it will throw an exception. the problem is that with **kwargs
u may specify as many parameters as u want (0 to n). U can check how many parameters the user entered (kwargs length) and then print an error message or whatever.
Thanks!
I second all that! Thanks for the explanation!
Thanks rubixC,
I'm not sure that's exactly what I need.
If I define the function like this:
def myfunction(self,**kwargs):pass,
I won't be able to make the user call the arguments _a_ and _b_. I won't be able to refer to them in the function either, like this:
def myfunction(self,**kwargs):print a,
because for all I know the user could have called this _a_ anything I have no way of finding out, right?
Hi Sofeng and rubixC, I have thought of a way to do what I wanted, but it doesn't look particularly elegant:
def myfunc(self, **kwargs):
kwargsdict = {}
expected_args = ["a","b","c"]
for key in kwargs.keys():
if key in expected_args:
kwargsdict[key] = kwargs[key]
else:
raise Exception("Unexpected Argument")
self.__myfunc_help(kwargsdict)
def __myfunc_help(self,a=None,b=None,c=None):
"real code here"
pass
#(not tested)
But I don't really like this solution... Emma
Hi Emma,
Thanks for giving us your solution. Have you tried asking on Stack Overflow? They have been helpful to me in the past.
That was easy! Thanks!
Thanks for the brief explanation. It was really useful. :-)
Thanks,
I love python magics :)
Emma --
First, you have to ask yourself why you raising the error is better than letting the system raise the error.
In other words, self.myfunc could consist of just:
self._myfunc_help(**kwargs)
Or, better, the caller could just call _myfunc_help directly.
You don't really need to copy from kwargs to kwargsdict. And you don't need to redundantly specify 'keys' in the for loop:
for key in kwargs:
if not key in expected:
raise ...
self._myfnc_help(**kwargs)
You could also play around with things like:
expected = set(['a', 'b', 'c'])
got = set(kwargs.keys())
if bool(got - expected):
raise ...
ces,
Thank you for your comment. I fixed the formatting of your comment by putting 4 spaces before each line of your code blocks.
Good morning everyone, I have an urgent question regarding *args and there is NOWHERE ELSE a discussion around it...
I need to pass TWO non-keyworded, variable-length argument lists to my class and instance. Somebody said that the word 'args' can be different since we use * in front... so my question is: can I pass something like
(someargs, *args, *myotherargs)
?
THANKS!! Angelica.
Excuse me all... the asteriscs * are not apprearing in my previous parenthesis... args should read *args, with asterix myotherargs should read *myotherargs, with asterix... someargs shouldn't have the asterix though..
thanks!
Angelica,
I fixed the formatting of your comment.
Regarding your question, I don't think there is a way to have two variable length argument lists. How about passing two lists as regular positional arguments?
Thanks Eliot, You are right, I tried that option last week. I already created my args as the sum of two lists and it worked... so I use args first as my plain variable length list in one method, and for the next method, I do args = args + moreargs. My class is running now!
Angelica.
This is great; clear as a bell, and not to be found in my Python book! I would be interested in knowing whether there are any wrinkles to keep in mind when using *args and *kwargs with classes, as opposed to functions.
Much love man. This is what I needed and you put it so clear. Thank you
Thanks for the clarification, and I think you've got the most creative and bizarre domain I've seen in a while. Cheerio.
Nice - clear and thorough, very helpful, thanks
Conventions aside, must they be named "args" and "kwargs"?
What's the significance of the '*' and '**'. Does the former declare a tuple and latter a dictionary?
John,
"args" and "kwargs" are not the required names-- you can use whatever names you like.
Regarding the significance of *
and **
, this is the special syntax used to specify variable length arguments.
Great, concise explanation :)
Thanks for the concise tutorial. Perfect.
Thanks, very helpful! Great blog
great concise explanation. thanks a ton!!
Thanks for the simple explanation!
So, I have a very specific question. I have function definition like this:
def my_func(var1='test', *args, **kwargs):
If I call that function like this:
my_func('arg1', 'arg2', 'arg3')
then 'arg1' seems to always be interpreted as the argument to var1 with only 'arg2' and 'arg3' being added to args. But what I wanted was for all of my arguments to be put in args. Is that possible?
I only want to override the default for var1 by explicitly doing so. I guess I wasn't counting on my keyword definition for var1 to also be positional in this case. Any ideas?
Doug,
You should probably not mix positional and keyword arguments as you're doing.
When moving a named argument changes the behavior, that's a clue that something is not right. Consider this,
my_func('arg1', 'arg2', 'arg3', var1='var1_arg')
which will throw a TypeError, because there are multiple values for var1. Ambiguity is bad, and Python doesn't know what to do.
How about doing something like
if not var1: var1='default_value'
in the body? That way you can keep a default value, and change it at will. To make this work, don't specify var1 in the function definition.
-Ryan
Thanks. The explanation was very helpful. I had been using my own homebrew method based on function arguments of dictionary (hash) type for passing named arguments. I was forced to do this in Perl as it had nothing of this sort built in. I was glad to find out that Python has this. This is one more reason to switch to Python.
Thanks, It helped me!
Thank you!
Kilian
Thanks for explaining this; I was getting tired of seeing this all over the Tipfy documentation and not understanding it.
Two thumbs up. Thanks.
This was very helpful in my work on fitting statistical distributions using scipy, thank you for helping me by posting this. Excellent explanation, well done.
James
Thank you for this, your explanation was very useful.
Wonderful post. Straight to the point! I wish the python doc were that clear.
Thank you
cool. nice and helpfull. thanks.
Excuse me all... the asteriscs * are not apprearing in my previous parenthesis... args should read args, with asterix myotherargs should read myotherargs, with asterix... someargs shouldn't have the asterix though..
I was glad to find out that Python has this. This is one more reason to switch to Python.
This is the perfect tutorial that I have read in my experience!Thanks
Nice post, very helpful. This was definitely the refresher on this piece of syntax that I needed.
Very educational .. i just took this post , translated it to spanish and did a few comments, you can see it on:
http://diegoaguilera.com/como-usar-args-y-kwargs-en-python.html
Thanks for the clear explanation. I was puzzled by this for quite a while.
Thank you so much for the clear explanation. It's been a real life saver.
great description! thanks.
short and clearly, thx!
Thanks for very Good explanation.
Thanks for kwargs...!
I'm trying to handle default values for this system, and I've got two ideas, wondering what others think.
defaults = {s0 : v0, s1 : v1} def test(**kwargs): defaults.update(kwargs) do_stuff(defaults)
And then another idea:
defaults = {s0 : v0, s1 : v1} def test(**kwargs): kwargs.setdefault(*defaults.items()) do_stuff(kwargs)
Is there a prettier way?
Great job, thanks.
Seriously, awesome. I keep forgetting and keep coming back to this site for the same old explanation.
Thanks for doing this.
Thanks for all this help. I have been to this site a few times now. This won't be the last.
Hi, thanks for this great help. Very valuable.
Very helpful. Thanks.
You are very good teacher! Thanks!
thanks a lot
Thanks a lot
Thank you for the clear & concise explanation.
thanks for the clear explanation, but why do you say **kwargs
passes 'a keyworded, variable-length argument list'?
What is that ? It took me some time to figure out that that is actually a Python dictionary. Why not call it that ?
Great explanation! I find myself coming to your blog often.
Great explanation, thank you so much.
Thx, This explanation are real cool!
Thanks, really helpful.
brilliant, thanks a bunch!
thanks!
I love straight-to-the-point explanations like this. Thanks!
Great explanation!
thanks. excellent explanation!
I love you. Too much? Then thank you very, very much. I've been trying to find a good explanation for a while now...
Just another thanks here :)
It looks like this is one of the basic concepts that many people seem to have a hard time finding either in docs or tutorials.
Beautifully explained here!
This is the best way to explain any topic. Thanks!
Very nice explanation of /*, the best i've ever found on the net.
Thanks for the explanation, very easy to understand and exactly what I was looking for.
Amazing how this post remains so useful even though it has been four years since it saw the light of day.
Thanks, I gained more insight into the use of the kargs argument even though I had already used them. The concepts are similar to the ones used in the command line parsing module argparse for giving instant POSIX behaviour to your python 2.7.x scripts:
http://docs.python.org/library/argparse.html
thanks for this!!! Super easy to understand!
This article was easy to understand. I saved it for my own reference.
Must be good to know an article 4 years old is still helping Python novices to this day.
Thanks for this, really useful!
thank you! simple and neat!
Helpful explanation. Thank you.
Thank you, easy and helpful)
Thanks for explanation, I liked your blog and added to my feeds, best regards!
This for this simply -yet, comprehensive tutorial on kwargs. Although there are lots of examples all over the web, but none comes close to explaining it as much as you did here.
Nice work.
Hey thanks for the amazing explanation.
Very easy and straightforward explanation. Thanks! ps: I came here because cs253 on Udacity course
Thanks so much. You have made our lives much easier.
disqus:2003518103
Thank you so much. You made it easy.
disqus:2782011780
It makes sense now!
disqus:2972235839
I just wonder if the order in which the arguments ({"arg3": 3, "arg2": "two"})are passed unordered to the function in the keyworded form example. Is it just to underline that you are calling the arg by their name so order doesn't matter... or I am getting it wrong?
disqus:3203281722
good post
disqus:3314099117
You should point out, that the keys in mydict have to be exactly named like the parameters of function. Otherwise it will throw a typeError
disqus:3428025496
It's really good!
disqus:3502626420
going through a python bootcamp now. 9 and 5 years on, your post is still helpful =) thanks!
disqus:3556273117