20

我的怀疑是,我想做的事情在 Python 中以一种干净的方式不太可行。下面是一些相互调用的嵌套函数。(一般来说,它们不必在词法范围内,但需要动态地相互调用。)

def outer() :
    s_outer = "outer\n"

    def inner() :
        s_inner = "inner\n"
        do_something()

    inner()

现在,当我调用时,do_something()我想进一步访问调用堆栈中调用函数的变量,在这种情况下s_outers_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") )

工作得很好。

我的两个问题是这些

  1. 有没有更好的方法来解决这个问题?(除了将各自的数据包装成字典并将这些字典显式传递给do_something()

  2. 是否有更优雅/更简洁的方式来实现该reach()功能?

干杯!

4

3 回答 3

7

我最终做的是

scope = locals()

scopedo_something. 这样我就不必到达,但我仍然可以访问调用者的局部变量字典。这与自己构建字典并传递它非常相似。

于 2013-04-06T07:27:21.663 回答
7

没有,在我看来,也不应该是优雅的实现方式,reach因为它引入了一个新的非标准间接,它真的很难理解、调试、测试和维护。正如 Python 的咒语 (try import this) 所说:

显式优于隐式。

所以,只需传递参数。来自未来的你会非常感谢今天的你。

于 2013-03-25T06:40:54.753 回答
3

有没有更好的方法来解决这个问题?(除了将各自的数据包装成字典并将这些字典显式传递给 do_something())

明确地传递 dicts 是一种更好的方法。

你的提议听起来很不合常规。当代码大小增加时,您必须将代码分解为模块化架构,并在模块之间使用干净的 API。它还必须是易于理解、易于解释并且易于移交给其他程序员来修改/改进/调试它的东西。您提出的建议听起来不是一个干净的 API,非常规,具有不明显的数据流。我怀疑它可能会让许多程序员看到它时脾气暴躁。:)

另一种选择是使函数成为类的成员,数据位于类实例中。如果您的问题可以建模为在数据对象上运行的多个函数,那么这可能会很好。

于 2013-04-07T22:00:52.883 回答