我怀疑我想做的事情在Python中不是那么干净。以下是一些相互调用的嵌套函数。 (通常,它们不必是词法范围的,但需要动态地相互调用。)
def outer() :
s_outer = "outer\n"
def inner() :
s_inner = "inner\n"
do_something()
inner()
现在,当我调用do_something()
时,我想在callstack的更上方访问调用函数的变量,在本例中为s_outer
和s_inner
。
不幸的是,nonlocal
关键字只有在do_something()
函数中定义inner()
时才能帮助我。但是,如果我将其定义为与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()
功能?
干杯!
答案 0 :(得分:4)
没有,在我看来,应该没有优雅的方式来实现reach
,因为这引入了一个非常难以理解,调试,测试和维护的新的非标准间接。正如Python口头禅(试试import this
)所说:
明确比隐含更好。
所以,只需传递参数即可。从今天起,你将来会非常感激你。
答案 1 :(得分:2)
我最终做的是
scope = locals()
并从scope
访问do_something
。这样我就无需访问,但我仍然可以访问调用者的局部变量字典。这非常类似于自己构建字典并传递它。
答案 2 :(得分:1)
有没有更好的方法来解决这个问题? (除了将相应的数据包装成dicts并将这些dicts明确地传递给do_something())
明确传递dicts是一种更好的方法。
你提出的建议听起来非常不同寻常。当代码大小增加时,您必须将代码分解为模块化体系结构,并在模块之间使用干净的API。它还必须易于理解,易于解释,并且易于交给另一个程序员来修改/改进/调试它。您提出的建议听起来像不一个干净的API,非常规,具有非明显的数据流。我怀疑它可能会让许多程序员在看到它时变得脾气暴躁。 :)
另一个选择是使函数成为类的成员,数据在类实例中。如果您的问题可以建模为在数据对象上运行的多个函数,那么这可能会很好。