[Tutor] dynamic argument lists
Kent Johnson
kent37 at tds.net
Sat Aug 30 13:59:27 CEST 2008
On Sat, Aug 30, 2008 at 5:09 AM, eShopping
<etrade.griffiths at dsl.pipex.com> wrote:
> I don't understand the difference between
>
> myfunc (**kwargs)
>
> and
>
> myfunc (kwargs)
>
> Would someone mind explaining this? I never managed to find a satisfactory
> explanation for what "**" means!
One is a function that takes keyword args, with the keyword args being
passed in a dict; the other is a function that just takes a dict as an
argument.
For example, here f() is a function of a single argument.:
In [18]: def f(x):
....: print x
The argument can be a string:
In [19]: f('foo')
foo
Or a dict:
In [20]: d=dict(a=1, b=2)
In [21]: f(d)
{'a': 1, 'b': 2}
f() doesn't take keyword arguments:
In [27]: f(a=1)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/Users/kent/<ipython console> in <module>()
TypeError: f() got an unexpected keyword argument 'a'
The ** notation means, pass the key/value pairs of the dict as keyword
args. Since f() doesn't accept keyword args, it fails the same way as
an explicit keyword:
In [22]: f(**d)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/Users/kent/<ipython console> in <module>()
TypeError: f() got an unexpected keyword argument 'a'
Here is a function that takes keyword args:
In [23]: def g(a=None, b=None):
....: print a, b
In [24]: g('foo')
foo None
Passing the dict without ** treats it as an ordinary argument. Here
the parameter 'a' is set to the dict; 'b' is None:
In [25]: g(d)
{'a': 1, 'b': 2} None
Using the ** syntax assigns the key/value pairs of the dict to the
keyword args of the function:
In [26]: g(**d)
1 2
The names of the keywords are still checked:
In [28]: d['c'] = 3
In [29]: g(**d)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/Users/kent/<ipython console> in <module>()
TypeError: g() got an unexpected keyword argument 'c'
You can define a function that accepts any keywords. This is the flip
side of passing keywords in a dict; the function receives a dict
containing the keywords:
In [30]: def h(**kwargs):
....: print kwargs
This particular function takes *only* keyword arguments:
In [31]: h(1)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/Users/kent/<ipython console> in <module>()
TypeError: h() takes exactly 0 arguments (1 given)
It accepts any keyword arguments. They appear in a dict named kwargs:
In [32]: h(a=1, b=2)
{'a': 1, 'b': 2}
Passing a dict directly doesnt' work:
In [33]: h(d)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/Users/kent/<ipython console> in <module>()
TypeError: h() takes exactly 0 arguments (1 given)
Using the ** syntax in the call works:
In [34]: h(**d)
{'a': 1, 'c': 3, 'b': 2}
There is also a similar * syntax for positional paramaters, and you
can use any combination of named positional, named keyword, * and **
args in the same function. See
http://docs.python.org/tut/node6.html#SECTION006700000000000000000
http://docs.python.org/ref/function.html
http://docs.python.org/ref/calls.html#calls
for more.
Kent
More information about the Tutor
mailing list