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 に答える