3

我正在使用 python 创建一个简单的调试器,并尝试在表达式成立时创建断点。我正在使用 eval 函数来评估该表达式。但它不起作用。

def traceit(frame, event, trace_arg):
    if event == 'line':
        if(eval('x == 5')):
             print 'stop here'


def fn():
    #the variable x is defined and used here

sys.settrace(traceit)
fn()
sys.settrace(None)
4

1 回答 1

3

您需要将字典作为参数传递给函数locals(以便它知道是什么!- 否则它只是在猜测,它会选择不是函数上下文的本地上下文)globalsevalxfn

f_locals您可以分别从和f_globals属性中的堆栈框架对象获取局部值和全局值。

我想你可能想要这样的东西:

eval('x == 5',frame.f_locals,frame.f_globals)

作为旁注,您可能实际上不需要eval这种(静态)案例:

if frame.f_locals.get('x') == 5:
   print "stop here"

这是一些“工作”代码(即它在正确的位置打印“停在这里”):

import sys

def traceit(frame, event, trace_arg):
    if event == 'line':
        if 'x' in frame.f_locals or 'x' in frame.f_globals:
            if(eval('x == 5',frame.f_locals,frame.f_globals)):
                print 'stop here'
    return traceit

sentinel = object()
def trace_no_eval(frame, event, trace_arg):
    if event == 'line':
        value = frame.f_locals.get('x',frame.f_globals.get('x',sentinel))
        if value is not sentinel and value == 5:
            print 'stop here'
    return traceit


def fn():
    for x in range(10):
        print x

sys.settrace(traceit)
fn()
sys.settrace(trace_no_eval)
fn()
sys.settrace(None)

正如你所说,这是一个作业,请不要盲目复制。花时间去理解它,真正理解发生了什么。

于 2013-01-10T20:29:07.277 回答