Newbie question: How do I add elements to **kwargs in a function?

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Wed Mar 18 06:13:00 CET 2009


En Tue, 17 Mar 2009 01:24:18 -0200, Aaron Garrett  
<aaron.lee.garrett at gmail.com> escribió:
> On Mar 16, 9:59 pm, Chris Rebert <c... at rebertia.com> wrote:
>> On Mon, Mar 16, 2009 at 7:48 PM, Aaron Garrett
>> <aaron.lee.garr... at gmail.com> wrote:
>> > I have spent quite a bit of time trying to find the answer on this
>> > group, but I've been unsuccessful. Here is what I'd like to be able to
>> > do:
>>
>> > def A(**kwargs):
>> >    kwargs['eggs'] = 1
>>
>> > def B(**kwargs):
>> >    print(kwargs)
>>
>> > def C(**kwargs):
>> >    A(**kwargs)
>> >    B(**kwargs)
>>
>> > I'd like to be able to make a call like:
>>
>> > C(spam=0)
>>
>> > and have it print
>> > {'spam': 0, 'eggs': 1}
>>
>> > But it doesn't do that. Instead, it gives
>> > {'spam': 0}
>>
>> > I was under the impression that kwargs is passed by reference and,
>>
>> It's not. Semantically, the dictionary broken up into individual
>> keyword arguments on the calling side, and then on the callee side, a
>> fresh dictionary is created from the individual arguments. So while
>> Python uses call-by-object, extra packing/unpacking takes place in
>> this case, causing copying, and thus your problem.
>
> Thank you for the explanation.

There is still a way of getting what you want -- you must pass the actual  
dictionary, and not unpack/repack the arguments:

def A(kwargs):    # no **
     kwargs['eggs'] = 1

def B(**kwargs):
     print(kwargs)

def C(**kwargs):
     A(kwargs)     # no **
     B(**kwargs)

C(spam=0)

-- 
Gabriel Genellina




More information about the Python-list mailing list