[Tutor] Need better understanding of **kwargs
wesley chun
wescpy at gmail.com
Sun Jun 7 07:10:10 CEST 2009
>> Hello, I thought I understood **kwargs until I stumbled with this
>> function:
>>
>> def changeflexion(myword, mytag, **dicty):
>> :
>>
>> but when I import the module and call:
>> a = conjugate.changeflexion('estaban', 'VLFin', conjugate.mydict)
>> I get this error:
>> TypeError: changeflexion() takes exactly 2 arguments (3 given)
>> Isn't the 3rd argument supposed to be a dictionary?
>
> No, **dicty means the function takes zero or more keyword parameters:
>
>>>> def f(a,b,**k):
>
> ... print a,b,k
> ...
>>>>
>>>> f(1,2) # no keyword parameters
>
> 1 2 {}
>>>>
>>>> f(1,2,c=3) # one keyword parameter
>
> 1 2 {'c': 3}
>>>>
>>>> f(1,2,{'c':3}) # a dictionary
>
> Traceback (most recent call last):
> File "<interactive input>", line 1, in <module>
> TypeError: f() takes exactly 2 arguments (3 given)
>
> But there is a syntax to pass keyword arguments as a dictionary:
>
>>>> f(1,2,**{'c':3})
>
> 1 2 {'c': 3}
bob and mark are both correct, in their own special way. :-) what they
really meant to say is something like this:
1. if your entire purpose of the function is to accept a dictionary of
values and process them like you do in your function, there's no need
to make it a kwargs dict. as bob suggested, you can just remove the
"**" and keep the rest as-is.
2. however, if you're calling the function where there are a variable
number of keyword arguments, like mark's example:
f('foo', 20, c=3, d=4, g='bar')
f('boo', -10, e=2.718, pi=3.14)
f('one', 'two', d=-40, e=2.718)
...where both the number of arguments may vary, or if the names may
vary, i.e., (c,d,g) vs. (e, pi) vs. (d, e), etc., then this is more of
a correct use case for a **kwargs variable. it's whole purpose is for
keyword arguments and not necessarily a mechanism to pass a dictionary
to a function even though you can do it.
one exception is when you're trying to cascade a kwargs dictionary to
begin with, IOW, you're trying to continue to pass it on to yet
another function:
def f1(...., **kwargs):
:
def f2(...., **kwargs):
:
if 'bar' not in kwargs: # add another value to kwargs
kwargs['bar'] = 'foo'
rv = f1(..., **kwargs) # process by passing to f1()
hope this helps!
-- wesley
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"Core Python Programming", Prentice Hall, (c)2007,2001
"Python Fundamentals", Prentice Hall, (c)2009
http://corepython.com
wesley.j.chun :: wescpy-at-gmail.com
python training and technical consulting
cyberweb.consulting : silicon valley, ca
http://cyberwebconsulting.com
More information about the Tutor
mailing list