How to get all named args in a dict?

Dave Angel davea at ieee.org
Thu May 14 20:46:49 EDT 2009


kj wrote:
> In <mailman.158.1242328059.8015.python-list at python.org> Dave Angel <davea at ieee.org> writes:
>
>
>
>   
>> kj wrote:
>>     
>>> In <mailman.113.1242254593.8015.python-list at python.org> Terry Reedy <tjreedy at udel.edu> writes:
>>>
>>>   
>>>       
>>>> kj wrote:
>>>>     
>>>>         
>>>>> Suppose I have the following:
>>>>>
>>>>> def foo(x=None, y=None, z=None):
>>>>>     d = {"x": x, "y": y, "z": z}
>>>>>     return bar(d)
>>>>>
>>>>> I.e. foo takes a whole bunch of named arguments and ends up calling
>>>>> a function bar that takes a single dictionary as argument, and this
>>>>> dictionary has the same keys as in foo's signature, so to speak.
>>>>>
>>>>> Is there some builtin variable that would be the same as the variable
>>>>> d, and would thus obviate the need to explicitly bind d?
>>>>>       
>>>>>           
>>>   
>>>       
>>>> Use the built-in function locals()
>>>>     
>>>>         
>>>>>>> def f(a,b):
>>>>>>>           
>>>>>>>               
>>>> 	x=locals()
>>>> 	print(x)
>>>>     
>>>>         
>>>   
>>>       
>>>>>>> f(1,2)
>>>>>>>           
>>>>>>>               
>>>> {'a': 1, 'b': 2}
>>>>     
>>>>         
>>> That's *exactly* what I was looking for.  Thanks!
>>>
>>> kynn
>>>
>>>
>>>   
>>>       
>> You already had a better answer from Chris Rebert:
>>     
>
>   
>> def foo(**kwargs):
>>    return bar(kwargs)
>>     
>
>   
>> kwargs at this point is exactly a dictionary of the named arguments to foo.
>>     
>
> I disagree.  If I defined foo as you show above, then there is no
> error checking on the named parameters passed to foo; anything
> goes.
>
>   
>> Because if you try to do anything in this function, you'll probably be 
>> adding more local variables. And then they'd be passed to bar as well.
>>     
>
> That problem is easily solved: just make "x = locals()" the first
> statement in the definition of foo.
>
> kynn
>   
Well, you caught me by surprise.  The name and number of locals is 
determined at compile time, not at run time.  But when I run an 
experiment, it seems you're right, that the dict changes as the function 
executes.

In Python 2.62 at least, the following function gives the following results:

def myfunc(x, y):
    print  locals()
    s = 42
    print locals()

myfunc(y=12, x=33)

{'y': 12, 'x': 33}
{'y': 12, 'x': 33, 's': 42, 'r': {'y': 12, 'x': 33}}
{'y': 12, 'x': 33}


So, if one wanted to call bar, but not till after one had defined new 
locals, you could do the following:

def foo(x=None, y=None, z=None):
     args = locals().copy()
     a = new stuff
     dosomestuff with a, and maybe y
     bar(args)

A shallow copy would be adequate in this case.

Thanks for the correction.



More information about the Python-list mailing list