292

What exactly do *args and **kwargs mean?

According to the Python documentation, from what it seems, it passes in a tuple of arguments.

def foo(hello, *args):
    print(hello)

    for each in args:
        print(each)

if __name__ == '__main__':
    foo("LOVE", ["lol", "lololol"])

This prints out:

LOVE
['lol', 'lololol']

How do you effectively use them?

Elazar
  • 20,415
  • 4
  • 46
  • 67
UberJumper
  • 20,245
  • 19
  • 69
  • 87

5 Answers5

279

Putting *args and/or **kwargs as the last items in your function definition’s argument list allows that function to accept an arbitrary number of arguments and/or keyword arguments.

For example, if you wanted to write a function that returned the sum of all its arguments, no matter how many you supply, you could write it like this:

def my_sum(*args):
    return sum(args)

It’s probably more commonly used in object-oriented programming, when you’re overriding a function, and want to call the original function with whatever arguments the user passes in.

You don’t actually have to call them args and kwargs, that’s just a convention. It’s the * and ** that do the magic.

The official Python documentation has a more in-depth look.

Mahdi Yusuf
  • 19,931
  • 26
  • 72
  • 101
Paul D. Waite
  • 96,640
  • 56
  • 199
  • 270
  • 6
    No sweat, you’re very welcome. Confused me for a while as well. If you’re getting into Python seriously I’d heartily recommend ‘Programming Python’ by Mark Lutz. – Paul D. Waite Nov 13 '08 at 14:48
  • 46
    Perhaps link to the tutorial which explains this in depth, and should be read by everyone: http://docs.python.org/tutorial/controlflow.html#more-on-defining-functions – Ali Afshar Nov 13 '08 at 15:02
  • 1
    @AliAfshar: Your link was all I needed, should've been the answer by itself. Thanks! – scorpiodawg Apr 17 '12 at 06:27
  • 3
    @PaulD.Waite: No problem. I wonder how many rookies found this error by trying to use your code, but were telling themselves "_I must be doing something wrong here, this answer has so many votes_" ;) Another upvote from me, because it is very clear and very good. – Tadeck Aug 16 '12 at 02:07
  • @Tadeck: I dread to think. Aw, thank you. – Paul D. Waite Aug 16 '12 at 09:15
  • 2
    @scorpiodawg Link only answers are frowned upon, since the site they link to could vanish, leaving the answer useless for future visitors. – George Stocker Jan 17 '13 at 14:48
97

Also, we use them for managing inheritance.

class Super( object ):
   def __init__( self, this, that ):
       self.this = this
       self.that = that

class Sub( Super ):
   def __init__( self, myStuff, *args, **kw ):
       super( Sub, self ).__init__( *args, **kw )
       self.myStuff= myStuff

x= Super( 2.7, 3.1 )
y= Sub( "green", 7, 6 )

This way Sub doesn't really know (or care) what the superclass initialization is. Should you realize that you need to change the superclass, you can fix things without having to sweat the details in each subclass.

S.Lott
  • 384,516
  • 81
  • 508
  • 779
  • 6
    This is one of the most helpful answers I have found on how to use `super`. This answer is more than 5 years old, but I guess this is still a great way of using `super` in Python 2.X, correct? – Amelio Vazquez-Reina Apr 04 '13 at 17:09
  • Yes, still the way to do it. –  Feb 06 '15 at 17:55
  • Thanks, but it would be great if you could provide some real example ,why and when to use it. In the above example what happens if I don that that? – TaraGurung Mar 26 '17 at 06:05
73

Notice the cool thing in S.Lott's comment - you can also call functions with *mylist and **mydict to unpack positional and keyword arguments:

def foo(a, b, c, d):
  print a, b, c, d

l = [0, 1]
d = {"d":3, "c":2}

foo(*l, **d)

Will print: 0 1 2 3

Community
  • 1
  • 1
orip
  • 73,323
  • 21
  • 116
  • 148
  • You can actually do also `*mydict` (not `**mylist`), but the result will be slightly different (and unexpected to some). – Tadeck Aug 16 '12 at 00:36
  • 3
    simple, concise, and an easy to follow example to illustrate the point. My favorite kind of answer! – NickO Mar 27 '13 at 16:48
  • 1
    @Tadeck You can do `*x` for any iterable and `**y` for any mapping type. Since a dict is both an iterable and a mapping you can do either. See also http://stackoverflow.com/questions/8601268/python-class-that-acts-as-mapping-for-unpacking – augurar Oct 20 '14 at 22:33
25

Another good use for *args and **kwargs: you can define generic "catch all" functions, which is great for decorators where you return such a wrapper instead of the original function.

An example with a trivial caching decorator:

import pickle, functools
def cache(f):
  _cache = {}
  def wrapper(*args, **kwargs):
    key = pickle.dumps((args, kwargs))
    if key not in _cache:
      _cache[key] = f(*args, **kwargs) # call the wrapped function, save in cache
    return _cache[key] # read value from cache
  functools.update_wrapper(wrapper, f) # update wrapper's metadata
  return wrapper

import time
@cache
def foo(n):
  time.sleep(2)
  return n*2

foo(10) # first call with parameter 10, sleeps
foo(10) # returns immediately
orip
  • 73,323
  • 21
  • 116
  • 148
20

Just to clarify how to unpack the arguments, and take care of missing arguments etc.

def func(**keyword_args):
  #-->keyword_args is a dictionary
  print 'func:'
  print keyword_args
  if keyword_args.has_key('b'): print keyword_args['b']
  if keyword_args.has_key('c'): print keyword_args['c']

def func2(*positional_args):
  #-->positional_args is a tuple
  print 'func2:'
  print positional_args
  if len(positional_args) > 1:
    print positional_args[1]

def func3(*positional_args, **keyword_args):
  #It is an error to switch the order ie. def func3(**keyword_args, *positional_args):
  print 'func3:'
  print positional_args
  print keyword_args

func(a='apple',b='banana')
func(c='candle')
func2('apple','banana')#It is an error to do func2(a='apple',b='banana')
func3('apple','banana',a='apple',b='banana')
func3('apple',b='banana')#It is an error to do func3(b='banana','apple')
Kaushik Ghose
  • 1,024
  • 12
  • 16