How to get all named args in a dict?

John Machin sjmachin at lexicon.net
Thu May 14 21:48:32 EDT 2009


On May 15, 10:46 am, Dave Angel <da... at ieee.org> wrote:
> kj wrote:
> > In <mailman.158.1242328059.8015.python-l... at python.org> Dave Angel <da... at ieee.org> writes:
>
> >> kj wrote:
>
> >>> In <mailman.113.1242254593.8015.python-l... at python.org> Terry Reedy <tjre... 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.

So don't call it again!

> 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.

As I (thought I had) demonstrated, *NO* copy would be adequate in that
case.

> Thanks for the correction.




More information about the Python-list mailing list