3

私のPythonコードには、次の行があります。

try:
    result = eval(command, self.globals, self.locals)
except SyntaxError:
    exec(command, self.globals, self.locals)

command変数は任意の文字列にすることができます。したがって、Pythonデバッガーは/pdbで開始され、 /が戻っているときにアクティブのままである可​​能性があります。私がやりたいのは、/から戻ったときに通常のプログラム実行が再開されることを確認することです。ただあなたにアイデアを与えるために、これは私が望むおおよその振る舞いです:evalexecevalexecevalexec

try:
    result = eval(command, self.globals, self.locals)
    try: self.globals['pdb'].run('continue')
    except: pass
except SyntaxError:
    exec(command, self.globals, self.locals)
    try: self.globals['pdb'].run('continue')
    except: pass

ただし、このtry行は実行前にデバッガーに表示されますが、デバッガーにコードを表示させたくありません。また、実際には機能しません...コードを繰り返す理由は、コードのデバッグを最小限に抑えるためです。それ以外の場合は、exceptブロックの後で実行できます。

では、どうすればこれを行うことができますか?

補足として:

次の行をIPythonまたはbpythonインタープリターに入力しようとすると、同じ問題が発生し、コードにステップインできることがわかります。

import pdb
pdb.set_trace()
next

ただし、標準のcpythonインタープリターでこれを行うと、pythonプロンプトに戻ります。この理由は明らかに、前者の2つはPythonで実装されており、最後の1つは実装されていないためです。しかし、私の願いは、すべてのコードがpythonの場合でも同じ動作を実現することです。

4

1 に答える 1

3

あなたが制御していない文字列をeval/execしているのではないかと少し心配していますが、あなたはそれを少し考え抜いたと思います。

最も簡単なのは、各ステップでスタックフレームをチェックし、目的のレベルに戻ったときに自動的に再開するようにpdbを説得することだと思います。簡単な修正プログラムでそれを行うことができます。以下のコードでは、特定の関数に戻ったときにpdbを自動的に再開させるだけなので、単純なevalに簡略化しています。トレースしたくない関数でPdb()。resume_here()を呼び出します。注意:再開はグローバルであり、再開ポイントは1つだけですが、必要に応じて変更できると確信しています。

コードを実行すると、デバッガーが機能foo()し、シングルステップを実行できますが、コードに戻るとすぐにbar()自動的に続行されます。

例えば

import sys
from pdb import Pdb

def trace_dispatch(self, frame, event, arg):
    if frame is self._resume_frame:
        self.set_continue()
        return
    return self._original_trace_dispatch(frame, event, arg)

def resume_here(self):
    Pdb._resume_frame = sys._getframe().f_back

# hotfix Pdb
Pdb._original_trace_dispatch = Pdb.trace_dispatch
Pdb.trace_dispatch = trace_dispatch
Pdb.resume_here = resume_here
Pdb._resume_frame = None

def foo():
    import pdb
    pdb.set_trace()
    print("tracing...")
    for i in range(3):
        print(i)

def bar():
    Pdb().resume_here()
    exec("foo();print('done')")
    print("returning")

bar()
于 2010-12-06T11:36:27.090 に答える