Namespaces, multiple assignments, and exec()
John O'Hagan
mail at johnohagan.com
Sun Dec 21 21:02:31 EST 2008
On Sat, 20 Dec 2008, John O'Hagan wrote:
> On Sat, 20 Dec 2008, Terry Reedy wrote:
> > John O'Hagan wrote:
> > > I have a lot of repetitive assignments to make, within a generator,
> > > that use a function outside the generator:
> > >
> > > var1 = func("var1", args)
> > > var2 = func("var2", args)
> > > var3 = func("var3", args)
> > > etc...
> > >
> > > In each case the args are identical, but the first argument is a string
> > > of the name being assigned. It works fine but I'd like to reduce the
> > > clutter by doing the assignments in a loop. I've tried using exec():
> > >
> > > for name in name_string_list:
> > > exec(name + ' = func(\"' + name + '\", args)')
> > >
> > > but in the local namespace it doesn't understand func(), and if I give
> > > it globals() it doesn't understand the args, which come from within the
> > > generator.
> > >
> > > What's a good way to do this kind of thing?
> >
> > Put everything in your own namespace
> >
> > myvars={}
> > for name in namelist:
> > myvars[name]=func(name,args)
>
> Likely I'm missing something, but don't I still have to do
>
> var1 = myvars['var1']
> var2 = myvars['var2']
> var3 = myvars['var3']
> ...etc.
>
> to make the assignments?
And of course I am missing the fact that I can now do the exec loop over
myvars{} in the local namespace.
Doing this, however, exposed some behaviour that surprises me. Inside my
generator, doing:
exec('foo = 7') in locals()
print foo
foo = 3
produces an UnboundLocalError. In case it's relevant, the error I get inside
the generator if I don't specify local()s is:
SyntaxError: unqualified exec is not allowed in function 'sequence_engine' it
contains a nested function with free variables
But doing the same thing in a simple test generator, even if it calls outside
functions, works as I expect.
Removing any subsequent reassignments of the same name fixes the error, and as
it happens I can do this, but I'm curious, without me posting the whole
generator (it's long), why doesn't the above exec() assignment work in that
context?
Thanks,
John
More information about the Python-list
mailing list