(2016年5月28日更新)EmacsでRealGUDを使用する
Emacsの誰にとっても、このスレッドは、OPで説明されているすべて(およびそれ以上)を使用して、
- RealGUDと呼ばれるEmacsの新しい重要なデバッガー
ipdb
。
- Emacsパッケージ
isend-mode
。
これら2つのパッケージの組み合わせは非常に強力で、OPで説明されている動作を正確に再現し、さらに多くのことを実行できます。
RealGUD for ipdbの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シェル(つまりbreakpoint
)を起動する別の場所にアプリオリを配置することです。次に、で事前定義されたハードコードされたさまざまな「ブレークポイント」間を「ジャンプ」できます。Ctrl-D
これにより、現在の埋め込みIPythonシェルが終了し、インタープリターがへの次の呼び出しにヒットするたびに再び停止しipsh()
ます。
このルートを使用する場合、「デバッグモード」を終了して後続のすべてのブレークポイントを無視する1つの方法ipshell.dummy_mode = True
は、Python ipshell
が上記で作成したオブジェクトの後続のインスタンス化をすべて無視するようにすることです。
!
、ブレークポイントで任意のpythonコマンドを実行するコマンドがあります