如何访问父模块的Globals()到子模块?

时间:2016-11-17 10:41:14

标签: python python-2.7 ipython

我在子模块中有一个函数需要操作父/解释器Globals(断言,验证)中的变量,如下所示:

import mymodule
mymodule.fun_using_main_interpreter_globals1()

如果我这样做,它会起作用:

mymodule.fun_using_main_interpreter_globals1(explicit_pass= globals() )

但是,如果我不通过explictely globals(),我怎样才能访问解释器/父globals()到我的子模块中?

在IPython中,它可以放在配置文件设置中。

2 个答案:

答案 0 :(得分:2)

我从来没有真正去过这片领域,但是看at the documentation这应该这样做:

caller_globals = dict(inspect.getmembers(inspect.stack()[1][0]))["f_globals"]

inspect模块允许您访问python解释器堆栈等。第二个元素(使用[1]访问)是调用者,堆栈帧是元组的第一个元素(使用[0]访问)并且它包含该上下文的当前全局字典(名为{ {1}})。

请注意,这会返回调用者的f_globals ,而不是被调用函数是子模块的模块之一。我一般认为这是不可能的,因为相同的模块可以是不同模块的子模块(子模块只是模块中的全局模块,并且不同模块共享相同的子模块对象是可能的)。

答案 1 :(得分:0)

我有这个工作用于局部变量,并在查找如何获取调用者上下文的全局变量时遇到了这篇文章。虽然这个主题有足够的信息来帮助我看到我所缺少的东西(感谢用户@ 6502),但我还是忍不住觉得如果我还没有让它工作,我可能会对这些信息感到困惑在这里,因此:

这是访问调用者上下文(本地或全局)中的变量的一种相对简单的方法,它在py2和py3中都有效:

import inspect
def furmat ( text ):
    # ... other initialization stuff ...
    this_frame = inspect.currentframe() # GET OUR FRAME HERE
    caller_frame = this_frame.f_back # GET CALLER'S FRAME HERE
    def caller_value ( key ):
        val = caller_frame.f_locals.get ( key ) # LOOKUP CALLER-LOCAL
        if val is not None:
            return val
        return caller_frame.f_globals[key] # LOOKUP CALLER-GLOBAL ( raise KeyError )
    # ... process text here, call caller_value() to query for variables in the caller's context
    del caller_frame # PREVENT MEMORY LEAKS PART 1
    del this_frame # AND PART 2

对于那些想要了解可能的动机的人,我构建了一个名为“furmat”的类似格式的函数,它可以在被{}包围的时候通过名称自动解析任何变量,如py3的f“”字符串,但这可以在py2中工作。示例调用如下所示:

from furmat import furmat
a = "AAA"
def test():
    b = "BBB"
    return furmat ( "{a}{b}" )
assert test() == "AAABBB"

注意它解析了局部变量{b}和全局变量{a}

我不是在这里发布furmat的源代码,因为它只有80行,并且依赖于我私人库中的六个其他文件,所以它有点超出了范围,但是在这个顶部的片段post是我用来查找格式字符串中提供的任何名称的值的确切方法(减去大多数错误处理以使示例更具可读性)。

除了上面给出的原因,我还想构建furmat,因为:

1)py2的unicode.format()如果你禁用字节和unicode之间的自动转换然后尝试取一个{!r},则抛出一个UnicodeError,因为repr()的输出总是一个字节(py2 str)对象所以你无法避免自动转换,

2)我不喜欢{!r}如何模糊地仅为非本地字符串打印b''或u''字符串前缀,这使我在mypy和单元测试期间经常在py2和py3之间切换时感到困惑,和

3)很有趣。