[Tutor] Need better understanding of **kwargs

Eduardo Vieira eduardo.susan at gmail.com
Mon Jun 8 19:28:35 CEST 2009


On Sat, Jun 6, 2009 at 11:10 PM, wesley chun<wescpy at gmail.com> wrote:
>>> 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
>

Thanks you all. I only had time to read the replies today. Now it's
more clear the meaning of **kwargs. I had also figured out that
without using ** the 3rd argument (dicty) worked fine.

Regards,

Eduardo


More information about the Tutor mailing list