【发布时间】:2018-02-18 23:01:37
【问题描述】:
我一直在用 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()
【问题讨论】:
-
您会感到困惑,因为您正在修改
f_locals。这基本上是未定义的行为。 -
修改
locals()返回的dict将不会影响解释器看到的局部变量。见这里:docs.python.org/3/library/functions.html#locals -
@juanpa.arrivillaga 此代码不会修改
locals()的返回值。它确实修改了框架的f_locals,但这也可能不是一个好主意。 -
@viraptor
locals返回frame.f_locals(至少在 cpython 中)。
标签: python python-3.x python-internals