从Python中调用命名空间获取本地人员

Pet*_*ter 32 python metaprogramming

我想从被调用的函数中检索Python中的局部变量.有没有办法做到这一点?我意识到这不适合大多数编程,但我基本上构建了一个调试器.例如:

def show_locals():
  # put something in here that shows local_1.

local_1 = 123
show_locals()  # I want this to show local_1.
Run Code Online (Sandbox Code Playgroud)

我把什么放在体内show_locals?如果我必须修改调用语句,我可以进行的最小修改是什么?

注意:show_locals它与调用者位于不同的模块时,这必须起作用.

Gar*_*ees 65

如果您正在编写调试器,则需要大量使用该inspect模块:

def show_callers_locals():
    """Print the local variables in the caller's frame."""
    import inspect
    frame = inspect.currentframe()
    try:
        print(frame.f_back.f_locals)
    finally:
        del frame
Run Code Online (Sandbox Code Playgroud)

  • [`inspect`文档](https://docs.python.org/3/library/inspect.html#the-interpreter-stack)解释了`del frame`. (6认同)
  • 为什么删除`finally`块中的`frame`是必要的?将帧对象保持在内存中的某种程度上是否昂贵?当然,这是一个小问题,但它让我感到困惑.另外,谢谢,这非常有帮助! (2认同)
  • 啊等等,我明白了。“超出范围”,从字面上看,意味着拥有局部变量的堆栈帧即将被释放。但是,“frame”恰好指向该堆栈帧。这就是他们所说的循环。好吧,我承认“delframe”很有用。OTOH 我不确定这个变量是否有必要。我认为函数体可以是 `print(inspect.currentframe().f_back.f_locals)` (2认同)

小智 7

也许值得指出的是,从调用者的堆栈帧读取的已接受答案中的技术:

import inspect
def read_from_caller(varname):
    frame = inspect.currentframe().f_back
    try:
        v = frame.f_locals[varname]
        return v
    finally:
        del frame
Run Code Online (Sandbox Code Playgroud)

还可以写入调用者的命名空间:

import inspect
def write_in_caller(varname, v):
    frame = inspect.currentframe().f_back
    try:
        frame.f_locals[varname] = v
    finally:
        del frame
Run Code Online (Sandbox Code Playgroud)

如果你把它放在一个名为“access_caller”的模块中,那么

import access_caller
access_caller.write_in_caller('y', x)
Run Code Online (Sandbox Code Playgroud)

是一种复杂的写作方式

y = x
Run Code Online (Sandbox Code Playgroud)

(我写这个作为一个新的答案,因为我没有足够的声誉点来写评论。)