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
45
Comments
—
Comments feed for this post
#2 Julien commented on 2008-05-16:
thanks for this explanation. It's pretty cool to have such informations easy to understand.
#4 mike commented on 2008-10-29:
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!
#5 Eliot commented on 2008-10-29:
Mike, I had not heard of Think Python. It looks like a great free Python resource.
#7 Volkan commented on 2008-11-13:
I have newly discovered your blog and it is awsome. Also this is a very good tip. Thanks you!
#8 Richie commented on 2008-11-22:
I too want to thank you for your explanation. Just started Python/Django and blogs like this really speed up the task.
#9 Protector one commented on 2009-01-13:
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.
#10 Eliot commented on 2009-01-20:
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.
#12 Emma commented on 2009-04-08:
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
#13 Eliot commented on 2009-04-15:
Emma, That's a good question-- I don't know the answer. If you find the answer, let me know.
#14 Michael Arp Sørensen commented on 2009-05-11:
Pretty usefull stuff. I found it usefull for my hobby project.
Python is so cool. :-)
#15 rubixC commented on 2009-05-13:
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.
#18 Emma commented on 2009-05-20:
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?
#19 Emma commented on 2009-05-21:
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
#20 Eliot commented on 2009-05-22:
Hi Emma,
Thanks for giving us your solution. Have you tried asking on Stack Overflow? They have been helpful to me in the past.
#24 ces commented on 2009-08-18:
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 myfunchelp 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 ...
#25 Eliot commented on 2009-08-19:
ces,
Thank you for your comment. I fixed the formatting of your comment by putting 4 spaces before each line of your code blocks.
#26 Angelica commented on 2009-08-27:
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.
#27 Angelica commented on 2009-08-27:
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!
#28 Eliot commented on 2009-08-27:
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?
#29 Angelica commented on 2009-08-31:
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.
#30 Thomas B. Higgins commented on 2009-09-02:
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.
#31 Sibande commented on 2009-09-06:
Much love man. This is what I needed and you put it so clear. Thank you
#32 mitjak commented on 2009-10-02:
Thanks for the clarification, and I think you've got the most creative and bizarre domain I've seen in a while. Cheerio.
#34 John commented on 2009-12-09:
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?
#35 Eliot commented on 2009-12-09:
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.
#40 Doug commented on 2010-02-03:
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?
#41 Ryan commented on 2010-02-09:
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
#42 Paul commented on 2010-02-22:
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.
Post a comment
About
I'm Eliot and this is my notepad for programming topics such as Python, Django, Ubuntu, Emacs, etc... more »
Search Blog
Tags
-
algorithms
(4)
-
aws
(8)
-
blogproject
(20)
-
c_cplusplus
(12)
-
cardstore
(8)
-
colinux
(2)
-
concurrency
(9)
-
conkeror
(2)
-
cygwin
(18)
-
datastructures
(15)
-
datetime
(3)
-
dell
(3)
-
django
(39)
-
emacs
(20)
-
files_directories
(10)
-
install_setup
(7)
-
javascript
(3)
-
keyboard
(6)
-
matplotlib
(5)
-
mercurial
(4)
-
nginx
(2)
-
preferences
(8)
-
processes
(3)
-
pyqt
(18)
-
python
(122)
-
ratpoison
(3)
-
regexes
(5)
-
rsync
(3)
-
softwaretools
(17)
-
sql
(13)
-
ssh
(7)
-
subversion
(6)
-
twisted
(6)
-
ubuntu
(60)
-
urxvt
(5)
-
vxworks
(25)
-
webservices
(4)
-
wmii
(7)
Blogroll
- Adam Gomaa
- Alex Clemesha
- Amir Salihefendic
- Armin Ronacher
- David Beazley
- David Ziegler
- Duncan McGreggor
- Gareth Rushgrave
- Glyph Lefkowitz
- Guido van Rossum
- Ian Bicking
- Jacob Kaplan-Moss
- James Bennett
- James Tauber
- Jesper Noehr
- Matt Harrison
- Nikolay Kolev
- Parand Darugar
- Peter Baumgartner
- Peter Bengtsson
- Rob Hudson
- Simon Willison
- Will McGugan
#1 Skawaii commented on 2008-02-13:
Thanks for the succinct explanation of args and *kwargs. You made it nice and easy to understand.