Why Does Modifying Parent Frame In Python Work Only For Module Frames?
Solution 1:
The f_locals
of a module stack frame are its globals()
!
You can verify this by printing the is
comparison with globals()
inside the modify
function:
def modify():
print(inspect.stack()[1][0].f_locals isglobals())
inspect.stack()[1][0].f_locals['a'] = 8888
With this change the output is:
$python3 modify.py
10False1020True8888
Modifying the dictionary returned by globals()
does work (see this question). It is explicitlydocumented that modules implement their namespace with a simple dict
:
Modules are imported by the
import
statement (see section The import statement). A module object has a namespace implemented by a dictionary object (this is the dictionary referenced by thefunc_globals
attribute of functions defined in the module).
However the dictionary returned by locals()
does not have to be the local namespace:
Note The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the interpreter.
In some versions of python2 modifying locals()
works when using the exec
statement inside the function. Try to add exec ''
inside the outer
function and see whether the output changes (it isn't guaranteed to change! However it is more likely).
Edit: On python 2.7.6 I can make it work if the stack frame uses the exec
statement and there is no assignment to a local variable in the code. For example with outer
defined as:
def outer():
exec('a = 10')
print(a)
modify()
print(a)
locals()['a'] = 9999print(a)
I get the output:
$python2modify.py10False8888999920True8888
But if I add a = 10
after the exec
as in:
def outer():
exec('a = 10')
a = 10print(a)
modify()
print(a)
locals()['a'] = 9999print(a)
The result is:
$python2 modify.py
10False101020True8888
I hope this shows you that the conditions in which assigning to locals work are really few and absolutely not reliable.
AFAIK in python3 the dictionary returned by locals()
is always just a copy of the real namespace, so modifying it never works. However there is no guarantee either.
The value returned by the f_locals
attribute is simply the value returned by locals()
at that point.
In summary: no, there is no reliable way to modify the local namespace of a generic stack frame. You cannot modify, delete nor add new local variables to a generic stack frame's namespace.
Post a Comment for "Why Does Modifying Parent Frame In Python Work Only For Module Frames?"