我怀疑我想做的事情在Python中不是那么干净 . 以下是一些相互调用的嵌套函数 . (通常,它们不必是词法范围的,但需要动态地相互调用 . )
def outer() :
s_outer = "outer\n"
def inner() :
s_inner = "inner\n"
do_something()
inner()
现在,当我调用 do_something()
时,我想在callstack上进一步访问调用函数的变量,在本例中为 s_outer
和 s_inner
.
不幸的是,只有在 inner()
函数内定义 do_something()
时, nonlocal
关键字才能帮助我 . 但是,如果我在与 outer()
相同的级别定义它,则 nonlocal
关键字将不起作用 .
但是,我想从各种其他函数调用 do_something()
,但始终在各自的上下文中执行它并访问它们各自的范围 .
感觉顽皮我然后写了一个小的访问者,我可以在 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") )
工作得很好 .
我的两个问题是这些
-
有没有更好的方法来解决这个问题? (除了将相应的数据包装成dicts并将这些dicts明确地传递给
do_something()
) -
是否有更优雅/更短的方式来实现
reach()
功能?
干杯!
3 回答
没有,并且在我看来,应该没有优雅的方式来实现
reach
,因为这引入了一个非常难以理解,调试,测试和维护的新的非标准间接 . 正如Python口头禅(试试import this
)所说:所以,只需传递参数 . 从今天开始,你们将来会非常感激你们 .
我最终做的是
并使
scope
可从do_something
访问 . 这样我就无需访问,但我仍然可以访问调用者的局部变量字典 . 这与自己构建字典并传递它非常相似 .明确地传递dicts是一种更好的方法 .
你提出的建议听起来不是一个干净的API,非传统的,具有非明显的数据流 . 我怀疑它可能会让许多程序员在看到它时变得脾气暴躁 . :)
另一种选择是使函数成为类的成员,数据在类实例中 . 如果您的问题可以建模为在数据对象上运行的多个函数,那么这可能会很好 .