tags:

views:

2887

answers:

8

In the following method, what does the * and ** do for param2? I'm new to Python...I assume it's a reference or pointer. Answers?

def foo(param1, *param2):
def bar(param1, **param2):
+1  A: 

From the Python documentation:

If there are more positional arguments than there are formal parameter slots, a TypeError exception is raised, unless a formal parameter using the syntax "*identifier" is present; in this case, that formal parameter receives a tuple containing the excess positional arguments (or an empty tuple if there were no excess positional arguments).

If any keyword argument does not correspond to a formal parameter name, a TypeError exception is raised, unless a formal parameter using the syntax "**identifier" is present; in this case, that formal parameter receives a dictionary containing the excess keyword arguments (using the keywords as keys and the argument values as corresponding values), or a (new) empty dictionary if there were no excess keyword arguments.

Chris Upchurch
+78  A: 

The *args and **kwargs ist a common idiom to allow arbitrary number of arguments to functions as described in the section more on defining functions in the the python documentation.

The *args will give you all funtion parameters a a list:

In [1]: def foo(*args):
   ...:     for a in args:
   ...:         print a
   ...:         
   ...:         

In [2]: foo(1)
1


In [4]: foo(1,2,3)
1
2
3

The **kwargs will give you all keyword arguments except for those corresponding to a formal parameter as a dictionary.

In [5]: def bar(**kwargs):
   ...:     for a in kwargs:
   ...:         print a, kwargs[a]
   ...:         
   ...:         

In [6]: bar(name="one", age=27)
age 27
name one

Both idioms can be mixed with normal arguments to allow a set of fixed and some variable arguments:

def foo(kind, *args, **kwargs):
   pass

An other usage of the *l idiom is to unpack argument lists when calling a function.

In [9]: def foo(bar, lee):
   ...:     print bar, lee
   ...:     
   ...:     

In [10]: l = [1,2]

In [11]: foo(*l)
1 2

In the upcoming python 3.0 it will be possible to use *l on the left side of an assignment (Extended Iterable Unpacking):

first, *rest = [1,2,3,4]
first, *l, last = [1,2,3,4]
Peter Hoffmann
You might want to mention that you can name them anything you want, the *, ** indicates whether its positional args or keyword args. ie. you could name them *foo and **bar.
camflan
You forgot the unpacking of keyword arguments !
PierreBdR
+6  A: 

The single * means that there can be any number of extra positional arguments. foo() can be invoked like foo(1,2,3,4,5). In the body of foo() param2 is a sequence containing 2-5.

The double ** means there can be any number of extra named parameters. bar() can be invoked like bar(1, a=2, b=3). In the body of bar() param2 is a dictionary containing {'a':2, 'b':3 }

With the following code:

def foo(param1, *param2):
    print param1
    print param2

def bar(param1, **param2):
    print param1
    print param2

foo(1,2,3,4,5)
bar(1,a=2,b=3)

the output is

1
(2, 3, 4, 5)
1
{'a': 2, 'b': 3}
nickd
+20  A: 

It's also worth noting that you can use * and ** when calling functions as well. This is a shortcut that allows you to pass multiple arguments to a function directly using either a list of a dictionary. For example, if you have the following function:

def foo(x,y,z):
    print "x=" + str(x)
    print "y=" + str(y)
    print "z=" + str(z)

You can do things like:

>>> mylist = [1,2,3]
>>> foo(*mylist)
x=1
y=2
z=3

>>> mydict = {'x':4,'y':5,'z':6}
>>> foo(**mydict)
x=4
y=5
z=6
lorin
It will also work with a tuple as parameter for the function.
Rodrigo
+5  A: 

Also, it's a good idea not to populate your interface signatures with these conventions. It's okay to use them for private implementations, but for a public API, they can often obscure meaning. They're basically advertising, "Hey, this function/method accepts anything!".

Zac
The django public api for db, uses this a lot and is easy to use, but it helps a lot that it is well documented.
Null303
A: 

I second Zac, from a style and clarity point of view, using named function/method arguments is superior. If you use pyLint, it will yell at you whenever you get tempted by the dark-side of "* magic". That's not to say it's not necessary and/or useful, it's just that (in my opinion) it's rare it's the only answer to your problem.

+3  A: 

Peter's answer is exceptional. I will only add that Python does not have function overloading like other languages, so to achieve the same effect, a programmer can use the *args and **kwargs conventions to allow the same function to be called with different inputs, similar to overloading.

kurosch
+1  A: 

I have to disagree when you say it's rare it's the only answer to a problem.

Actually, I have one problem right now which I believe could be very well solved using **kwargs. I have a class constructor which takes 20 parameters, 16 of them optional. Using **kwargs, I'd have only 5 parameters on the function definition and the effect would be the same with a much more organized code.

Of course, it's important that, when it's used, the user comments the whereabouts of the code to let possible readers know the reason this solution is being used.

Rodrigo
It's a good idea to document what those optional parameters you look for in **kwargs in the function docstring.
David Locke