> Please forgive me, but I'm really trying to wrap my brain around the
> behavior of exec() in Python 3. Here's a quote from the documentation:
> "In all cases, if the optional parts are omitted, the code is
> executed in the current scope."
> This is referring to the optional use of the globals/locals parameters
> and seems to indicate that if they're omitted the code executes in the
> scope where the exec() appeared.
That's right, but in some cases the locals can't be changed. I'll
document this better.
> Now, I realize that exec() became a function in Python 3. However,
> regardless of that, is it really the intent that exec() not be allowed
> to ever modify any local variable of a function? In other words, do I
> really have to do this?
> def foo():
> ldict = locals()
> exec("a=42",globals(),ldict)
> a = ldict['a']
> print(a)
Yes, if you really need "a" as a local afterwards.
> I would appreciate some greater clarity on this matter this go around.
> Specifically, what is the approved way to have exec() modify the local
> environment of a function?
There is none. To modify the locals of a function on the fly is not
possible without several consequences: normally, function locals are not
stored in a dictionary, but an array, whose indices are determined at
compile time from the known locales. This collides at least with new
locals added by exec. The old exec statement circumvented this, because
the compiler knew that if an exec without globals/locals args occurred
in a function, that namespace would be "unoptimized", i.e. not using the
locals array. Since exec() is now a normal function, the compiler does
not know what "exec" may be bound to, and therefore can not treat is
specially.
|