我在子模块中有一个函数需要操作父/解释器Globals(断言,验证)中的变量,如下所示:
import mymodule
mymodule.fun_using_main_interpreter_globals1()
如果我这样做,它会起作用:
mymodule.fun_using_main_interpreter_globals1(explicit_pass= globals() )
但是,如果我不通过explictely globals(),我怎样才能访问解释器/父globals()到我的子模块中?
在IPython中,它可以放在配置文件设置中。
答案 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)很有趣。