保持函数名称空间在IPython中进行调试

时间:2013-12-13 23:34:33

标签: python debugging ipython

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

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

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

并在IPython提示符下写道:

>> run script.py

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

>> a

我会回来1

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

>> runfunction foo(1,2)
>> z

并确认z的值为3

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

如果此功能不存在,为了调试目的,检查函数中变量值的建议方法是什么,尽管可能不是每次时间运行它?

2 个答案:

答案 0 :(得分:4)

你可以使用sys.settrace,这是一个例子,我将本地dict保存到wrap函数的一个属性:

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

输出:

{'y': 2, 'x': 1, 'z': 3}

如果你想要它是全局变量,你可以使用locals dict更新全局字典。

答案 1 :(得分:0)

在这里进行典型的调试有什么问题?

> run -d program.py
> b program.py:282 #(line#)

您甚至可以使用以下内容设置条件:

> condition 2 a == 2 # where 2 is the breakpoint, 1 is by default first line

您可以在该范围内使用断点检查该选项。