如何在 Python 中查找变量?
How are variables looked up in Python?
我一直在试验 Python 并观察到一些我不理解的行为。
我认为执行查找时会发生什么:
- 检查当前帧中的局部变量
- 如果找不到变量,先尝试外框
- 重复1和2,直到没有更多的外框,如果没有找到变量,抛出
NameError
这与print(x)
的第一次调用是一致的,因为我已经将x
强制到第一个外框。
然而,print(x)
的第二次调用失败并显示 NameError
,这让我感到困惑,因为 x
存在于局部变量中。
谢谢!
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()
如果您查看 https://docs.python.org/3/library/inspect.html,您会发现所有官方用法都是为了...检查值。
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.
没有描述修改的安全性,您可以假设如果您想修改框架或您从该模块获得的其他内容,您只能靠自己了。 None 您所做的更改保证会传播回当前状态的内部表示。
我一直在试验 Python 并观察到一些我不理解的行为。
我认为执行查找时会发生什么:
- 检查当前帧中的局部变量
- 如果找不到变量,先尝试外框
- 重复1和2,直到没有更多的外框,如果没有找到变量,抛出
NameError
这与print(x)
的第一次调用是一致的,因为我已经将x
强制到第一个外框。
然而,print(x)
的第二次调用失败并显示 NameError
,这让我感到困惑,因为 x
存在于局部变量中。
谢谢!
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()
如果您查看 https://docs.python.org/3/library/inspect.html,您会发现所有官方用法都是为了...检查值。
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.
没有描述修改的安全性,您可以假设如果您想修改框架或您从该模块获得的其他内容,您只能靠自己了。 None 您所做的更改保证会传播回当前状态的内部表示。