保持函数命名空间处于活动状态以便在 IPython 中进行调试

jme*_*jme 3 python debugging ipython

在IPython中,有没有办法将函数的命名空间导入到交互环境中?例如,如果我有一个脚本,例如script.py

def foo(x,y):
    z = x + y
    return z

a = 1
b = 2
c = foo(a,b)
Run Code Online (Sandbox Code Playgroud)

在 IPython 提示符下我写:

>> run script.py
Run Code Online (Sandbox Code Playgroud)

中定义的所有内容都script.py成为我环境的一部分,所以如果我写:

>> a
Run Code Online (Sandbox Code Playgroud)

我会回来的1

我想要做的是能够将我调用的函数的名称空间转储到我的解释器名称空间中,以便我可以检查对象。就像是:

>> runfunction foo(1,2)
>> z
Run Code Online (Sandbox Code Playgroud)

并得到 的z值为3

我知道ipdb.set_trace(),我可以将其添加到函数末尾以自动进入调试器,但我可能不想每次都这样做。

如果此功能不存在,出于调试目的检查函数内变量值的推荐方法是什么(尽管可能不是每次运行它时)?

HYR*_*YRY 5

您可以使用sys.settrace,这是一个示例,我将本地字典保存到包装函数的属性中:

import sys

def get_locals(func):
    def wrap(*args, **kw):
        sys.settrace(tracefunc)
        try:
            res = func(*args, **kw)
        finally:
            sys.settrace(None)
        return res

    def tracefunc(frame, event, arg):
        if event == "return":
            if frame.f_code is func.func_code:
                wrap.last_res = frame.f_locals
        return tracefunc    

    return wrap

@get_locals
def foo(x,y):
    z = x + y
    return z

def bar(x, y):
    z = x - y
    return z

a = 1
b = 2
c = foo(a, b)
d = bar(a, b)

print foo.last_res
Run Code Online (Sandbox Code Playgroud)

输出:

{'y': 2, 'x': 1, 'z': 3}
Run Code Online (Sandbox Code Playgroud)

如果你希望它是全局的,你可以用本地字典更新全局字典。