(2016 年 5 月 28 日の更新) Emacs での RealGUD の使用
Emacsの誰にとっても、このスレッドは、OPで説明されているすべて(およびその他)を使用して達成する方法を示しています
- RealGUDと呼ばれる Emacs の新しい重要なデバッガーは、任意のデバッガー (を含む
ipdb
) で動作します。
- Emacs パッケージ
isend-mode
.
これら2つのパッケージの組み合わせは非常に強力で、OPで説明されている動作を正確に再現し、さらに多くのことを行うことができます.
ipdb の RealGUDの wiki 記事に関する詳細情報。
元の答え:
このスレッドで言及されているすべてのことを含め、Python をデバッグするためのさまざまな方法を試した後、IPython で Python をデバッグするための私の推奨方法の 1 つは、組み込みシェルを使用することです。
カスタム組み込み IPython シェルの定義:
スクリプトに以下を追加しPYTHONPATH
て、メソッドを使用できるようにしipsh()
ます。
import inspect
# First import the embed function
from IPython.terminal.embed import InteractiveShellEmbed
from IPython.config.loader import Config
# Configure the prompt so that I know I am in a nested (embedded) shell
cfg = Config()
prompt_config = cfg.PromptManager
prompt_config.in_template = 'N.In <\\#>: '
prompt_config.in2_template = ' .\\D.: '
prompt_config.out_template = 'N.Out<\\#>: '
# Messages displayed when I drop into and exit the shell.
banner_msg = ("\n**Nested Interpreter:\n"
"Hit Ctrl-D to exit interpreter and continue program.\n"
"Note that if you use %kill_embedded, you can fully deactivate\n"
"This embedded instance so it will never turn on again")
exit_msg = '**Leaving Nested interpreter'
# Wrap it in a function that gives me more context:
def ipsh():
ipshell = InteractiveShellEmbed(config=cfg, banner1=banner_msg, exit_msg=exit_msg)
frame = inspect.currentframe().f_back
msg = 'Stopped at {0.f_code.co_filename} at line {0.f_lineno}'.format(frame)
# Go back one level!
# This is needed because the call to ipshell is inside the function ipsh()
ipshell(msg,stack_depth=2)
次に、コードで何かをデバッグしたいときはいつでも、ipsh()
オブジェクトの検査などを行う必要がある場所に配置します。たとえば、my_function
以下をデバッグしたいとします。
それを使用して:
def my_function(b):
a = b
ipsh() # <- This will embed a full-fledged IPython interpreter
a = 4
次に、次のいずれかの方法で呼び出しmy_function(2)
ます。
- Unix シェルからこの関数を呼び出す Python プログラムを実行する
- または、IPython から直接呼び出すことによって
どのように呼び出しても、インタープリターは という行で停止しますipsh()
。完了したら実行できCtrl-D
、Python は実行を再開します (行った変数の更新を含む)。通常の IPython IPython シェル (上記のケース 2) からコードを実行する場合、新しい IPython シェルは呼び出し元のシェル内にネストされることに注意してください。これはまったく問題ありませんが、注意が必要です。いずれにせよ、インタープリターが の場所で停止すると、 ( である)ipsh
の値を検査したり、定義されている関数やオブジェクトを確認したりできます。a
2
問題:
上記のソリューションを使用して、コード内の任意の場所で Python を停止し、本格的な IPython インタープリターにドロップすることができます。残念ながら、スクリプトを呼び出すと、ブレークポイントを追加または削除することはできず、非常にイライラします。私の意見では、これがIPython が Python の優れたデバッグ ツールになるのを妨げている唯一の理由です。
今できる最善のこと:
回避策はipsh()
、Python インタープリターが IPython シェル (つまり a) を起動する別の場所に先験的に配置することですbreakpoint
。次に、事前に定義されたハードコードされたさまざまな「ブレークポイント」の間を で「ジャンプ」できます。Ctrl-D
これにより、現在の組み込み IPython シェルが終了し、インタープリターが への次の呼び出しにヒットするたびに再び停止しipsh()
ます。
このルートに進む場合、「デバッグ モード」を終了し、後続のすべてのブレークポイントを無視する 1 つの方法はipshell.dummy_mode = True
、Python がipshell
上で作成したオブジェクトの後続のインスタンス化を無視するようにすることです。