首页 文章

在Python中访问调用函数的变量

提问于
浏览
10

我怀疑我想做的事情在Python中不是那么干净 . 以下是一些相互调用的嵌套函数 . (通常,它们不必是词法范围的,但需要动态地相互调用 . )

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

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

    inner()

现在,当我调用 do_something() 时,我想在callstack上进一步访问调用函数的变量,在本例中为 s_outers_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 回答

  • 2

    没有,并且在我看来,应该没有优雅的方式来实现 reach ,因为这引入了一个非常难以理解,调试,测试和维护的新的非标准间接 . 正如Python口头禅(试试 import this )所说:

    明确比隐含更好 .

    所以,只需传递参数 . 从今天开始,你们将来会非常感激你们 .

  • 0

    我最终做的是

    scope = locals()
    

    并使 scope 可从 do_something 访问 . 这样我就无需访问,但我仍然可以访问调用者的局部变量字典 . 这与自己构建字典并传递它非常相似 .

  • 4

    有没有更好的方法来解决这个问题? (除了将相应的数据包装成dicts并将这些dicts明确地传递给do_something())

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

    你提出的建议听起来不是一个干净的API,非传统的,具有非明显的数据流 . 我怀疑它可能会让许多程序员在看到它时变得脾气暴躁 . :)

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

相关问题