tags:

views:

2981

answers:

5

What exactly does *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?

+21  A: 

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 anonymous 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 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.

Paul D. Waite
Thats amazing.Thank you.
UberJumper
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
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 A
+4  A: 

You should find everything you want to know in this article.

fivebells
+12  A: 

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
+6  A: 

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

orip
+6  A: 

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