Saltycrane logo

Sofeng's Blog

Notes on Python, Django, and web development on Ubuntu Linux

    

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 = (1, "two", 3)
test_var_args_call(*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", "arg1": 1}
test_var_args_call(**kwargs)

Results:

arg1: 1
arg2: two
arg3: 3
See also (updated 2009-04-12):

Reference: Core Python Programming, Second Edition, Section 11.6

22 Comments


#1 Skawaii commented, on February 13, 2008 at 1:46 p.m.:

Thanks for the succinct explanation of args and *kwargs. You made it nice and easy to understand.


#2 Julien commented, on May 16, 2008 at 8:01 a.m.:

thanks for this explanation. It's pretty cool to have such informations easy to understand.


#3 Dmitry commented, on October 28, 2008 at 12:09 a.m.:

Thanks for your explanation.


#4 mike commented, on October 29, 2008 at 1:39 p.m.:

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 sofeng commented, on October 29, 2008 at 6:34 p.m.:

Mike, I had not heard of Think Python. It looks like a great free Python resource.


#6 Katja commented, on October 31, 2008 at 10:43 a.m.:

Awesome! This is THE explanation I was looking for :).


#7 Volkan commented, on November 13, 2008 at 2:56 a.m.:

I have newly discovered your blog and it is awsome. Also this is a very good tip. Thanks you!


#8 Richie commented, on November 22, 2008 at 2:35 p.m.:

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 January 13, 2009 at 4:22 a.m.:

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 sofeng commented, on January 20, 2009 at midnight:

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.


#11 John McCollum commented, on February 16, 2009 at 11:43 a.m.:

Excellent, clear explanation. Thanks for the post.


#12 Emma commented, on April 8, 2009 at 2:09 p.m.:

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 Sofeng commented, on April 15, 2009 at 9:16 p.m.:

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 May 11, 2009 at 12:12 p.m.:

Pretty usefull stuff. I found it usefull for my hobby project.

Python is so cool. :-)


#15 rubixC commented, on May 13, 2009 at 8:32 a.m.:

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.


#16 Ubay Oramas commented, on May 15, 2009 at 9:53 a.m.:

Thanks!


#17 Nicolas commented, on May 19, 2009 at 8:44 p.m.:

I second all that! Thanks for the explanation!


#18 Emma commented, on May 20, 2009 at 11:44 a.m.:

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 May 21, 2009 at 9:02 a.m.:

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 sofeng commented, on May 22, 2009 at 1:58 p.m.:

Hi Emma,
Thanks for giving us your solution. Have you tried asking on Stack Overflow? They have been helpful to me in the past.


#21 Amit commented, on June 1, 2009 at 10:18 a.m.:

That was easy! Thanks!


#22 Joshua commented, on June 28, 2009 at 11:02 p.m.:

Thanks for the brief explanation. It was really useful. :-)

Post a comment

Required
Required, but not displayed
Optional

Format using Markdown. (No HTML.)
  • Code blocks: prefix each line by at least 4 spaces or 1 tab
  • Code span: surround with backticks
  • Blockquotes: prefix lines to be quoted with >
  • Links: <URL>
  • Links w/ description: [description](URL)
Created with Django | Hosted by Slicehost