def outer():
s_outer = "outer\n"
def inner():
s_inner = "inner\n"
do_something()
inner()
我希望do_something
中的代码能够访问调用函数调用栈上方的变量,例如s_outer
和s_inner
。更一般地,我想从各种其他函数调用它,但始终在它们各自的上下文中执行,并访问它们各自的作用域(实现动态作用域)。
我知道在Python 3.x中, nonlocal
关键字允许从inner
中访问s_outer
。不幸的是,如果do_something
不是在inner
中定义,则不能帮助它。否则,inner
不是一个词法封闭范围(同样,除非do_something
在outer
中定义,否则outer
也不是)。
我发现可以使用标准库inspect
来检查堆栈帧,并创建了一个小访问器,可以从do_something()
内部调用它,如下所示:
def reach(name):
for f in inspect.stack():
if name in f[0].f_locals:
return f[0].f_locals[name]
return None
然后
def do_something():
print( reach("s_outer"), reach("s_inner") )
工作得非常好。
“reach”能否更简单地实现?还有哪些方法可以解决这个问题?
outer
内部调用了inner
,但是想象一下,如果你返回inner
,然后做类似于outer()()
这样的事情,你的方法仍然有效吗? - Mitarnonlocal
已经可以遍历封闭作用域了。目标是将调用者视为封闭作用域(动态作用域),即使在 Python 中它实际上并不是(Python 实现了词法作用域,就像几乎所有现代语言一样)。OP 遍历堆栈是因为堆栈可以告诉你谁是调用者。 - Karl Knechtel