I have been experimenting with Python and observed some behaviour that I don't understand.
What I think happens when performing a look-up:
NameError
This is consistent with the 1st call of print(x)
, as I have forced x
into the first outer frame.
However, the 2nd call of print(x)
fails with a NameError
, which confuses me as x
exists in the local variables.
Thanks!
import inspect
def test():
frame_inner = inspect.currentframe()
print(locals()) # { 'frame_inner': A }
frame_outer = inspect.getouterframes(frame_inner)[1].frame
y = 'y'
frame_outer.f_locals['x'] = 'x'
print(locals()) # { 'frame_inner': A, 'frame_outer': B, 'y': 'y' }
print(y) # y
print(x) # x
del frame_outer.f_locals['x']
frame_inner.f_locals['x'] = 'x'
print(locals()) # { 'frame_inner': A, 'frame_outer': B, 'y': 'y', 'x': 'x' }
print(y) # y
print(x) # NameError: name 'x' is not defined
test()
If you look at https://docs.python.org/3/library/inspect.html you'll find that all the official usage is for... inspecting the values.
The inspect module provides several useful functions to help get information about live objects such as modules, classes, methods, functions, tracebacks, frame objects, and code objects.
No safety of modification is described and you can assume that if you want to modify the frames or other things you get from this module, you're on your own. None of the changes you make are guaranteed to be propagated back to the internal representation of the current state.