exec with partial globals

Chris Angelico rosuav at gmail.com
Tue Oct 30 08:28:43 EDT 2012


On Tue, Oct 30, 2012 at 11:00 PM, Helmut Jarausch
<jarausch at igpm.rwth-aachen.de> wrote:
> Hi,
>
> I'd like to give the user the ability to enter code which may only rebind
> a given set of names but not all ones.
>
> How can 'filter' the gobal namespace such that modifying 'A' is allowed
> but any attempt to modify 'B' should give an exception.

I don't know of any way to do that _as such_, but you can simply
follow up the exec with direct retrieval from the globals.

>>> a=1; b=2
>>> code=compile("a=7",'','exec')
>>> ns={'a':0}
>>> exec(code,ns)
>>> a=ns["a"]

(Incidentally, it's normal to use lower case for most names, reserving
the leading uppercase letter for types/classes.)

The exec'd code gets its own namespace (defined by the dictionary,
same as you were doing - note that the 'a' inside that namespace has
nothing to do with the 'a' outside it), and then you explicitly fetch
the values you want.

A slightly more sophisticated example might include a list of shared
variables, for example:

shared = ['a']
outer = globals()
ns = {v:outer[v] for v in shared}
exec(code,ns);
for v in shared: outer[v]=ns[v]

Untested but should work. (Is there any way to directly apply filter()
to a dictionary? That's what I'm really looking for here.)

ChrisA



More information about the Python-list mailing list