193

私が読んだところによると、Python でコードをデバッグするには 2 つの方法があります。

  • pdbまたはなどの従来のデバッガーを使用しますipdbcこれは、 for continuenfor step-oversforなどのコマンドをサポートしてstep-intoいますが、オブジェクトの検査に非常に役立つ IPython シェルに直接アクセスすることはできません。

  • コードに IPython シェルを埋め込んIPythonを使用 する。を実行して、コードで使用できます。プログラム/スクリプトがステートメントにヒットすると、IPython シェルにドロップされます。これにより、オブジェクトの完全な検査と、すべての IPython グッズを使用した Python コードのテストが可能になります。ただし、使用すると、便利なキーボード ショートカットを使用してコードを段階的に進めることができなくなります。from IPython import embedembed()embed()embed()

両方の長所を組み合わせる方法はありますか? いえ

  1. 便利な pdb/ipdb キーボード ショートカットを使用して、コードを段階的に実行でき ます。
  2. そのようなステップ (たとえば、特定のステートメント) で、本格的なIPython shellにアクセスできます。

MATLABのようなIPython デバッグ:

このタイプの「強化されたデバッグ」の例は、MATLAB で見つけることができます。この場合、ユーザーは常にMATLAB エンジン/シェルに完全にアクセスでき、コードを段階的に実行したり、条件付きブレークポイントを定義したりできます。これは、MATLAB から IPython に移行するときに最も見逃されるデバッグ機能です。

Emacs およびその他のエディターでの IPython のデバッグ:

質問をあまり具体的にしたくありませんが、私は主に Emacs で作業しているので、この機能を Emacs に組み込む方法はあるのでしょうか。理想的には、Emacs (またはエディター) を使用すると、プログラマーはコードの任意の場所にブレークポイントを設定し、インタープリターまたはデバッガーと通信して、選択した場所で停止し、その場所で完全な IPython インタープリターを実行できます。

4

15 に答える 15

80

IPython の%pdbマジックを使用できます。IPython を呼び出すだけ%pdbで、エラーが発生すると、自動的に にドロップされipdbます。すぐに足を踏み入れることはありませんが、ipdb後で足を踏み入れます。

これにより、個々の関数のデバッグが簡単になります。ファイルを読み込んで%load関数を実行するだけだからです。assert正しい位置でエラーを強制することができます。

%pdbラインマジックです。%pdb on%pdb 1%pdb offまたはと呼び%pdb 0ます。引数なしで呼び出すと、トグルとして機能します。

于 2017-04-14T14:14:04.773 に答える
40

(2016 年 5 月 28 日の更新) Emacs での RealGUD の使用

Emacsの誰にとっても、このスレッドは、OPで説明されているすべて(およびその他)を使用して達成する方法を示しています

  1. RealGUDと呼ばれる Emacs の新しい重要なデバッガーは、任意のデバッガー (を含むipdb) で動作します。
  2. 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)ます。

  1. Unix シェルからこの関数を呼び出す Python プログラムを実行する
  2. または、IPython から直接呼び出すことによって

どのように呼び出しても、インタープリターは という行で停止しますipsh()。完了したら実行できCtrl-D、Python は実行を再開します (行った変数の更新を含む)。通常の IPython IPython シェル (上記のケース 2) からコードを実行する場合、新しい IPython シェルは呼び出し元のシェル内にネストされることに注意してください。これはまったく問題ありませんが、注意が必要です。いずれにせよ、インタープリターが の場所で停止すると、 ( である)ipshの値を検査したり、定義されている関数やオブジェクトを確認したりできます。a2

問題:

上記のソリューションを使用して、コード内の任意の場所で Python を停止し、本格的な IPython インタープリターにドロップすることができます。残念ながら、スクリプトを呼び出すと、ブレークポイントを追加または削除することはできず、非常にイライラします。私の意見では、これがIPython が Python の優れたデバッグ ツールになるのを妨げている唯一の理由です。

今できる最善のこと:

回避策はipsh()、Python インタープリターが IPython シェル (つまり a) を起動する別の場所に先験的に配置することですbreakpoint。次に、事前に定義されたハードコードされたさまざまな「ブレークポイント」の間を で「ジャンプ」できます。Ctrl-Dこれにより、現在の組み込み IPython シェルが終了し、インタープリターが への次の呼び出しにヒットするたびに再び停止しipsh()ます。

このルートに進む場合、「デバッグ モード」を終了し、後続のすべてのブレークポイントを無視する 1 つの方法はipshell.dummy_mode = True、Python がipshell上で作成したオブジェクトの後続のインスタンス化を無視するようにすることです。

于 2014-04-30T12:28:48.020 に答える
19

pudbから IPython セッションを開始し、必要に応じてデバッグ セッションに戻ることができます。

ところで、ipdb は舞台裏で IPython を使用しており、実際には TAB 補完やマジッ​​ク コマンド (で始まるもの%) などの IPython 機能を使用できます。ipdb に問題がなければ、%runやなどのコマンドを使用して IPython から開始できます%debug。ipdbセッションは、スタックトレースなどで上下に移動できるという意味で、実際にはプレーンなIPythonセッションよりも優れています。「オブジェクト検査」のためにipdbに欠けているものは何ですか?

また、Emacs >= 24.3 にバンドルされている python.el には、素晴らしい ipdb サポートがあります。

于 2013-06-01T19:10:09.077 に答える
7

「!」を前に付ける pdb で入力するコマンドへの記号は、IPython シェルで何かを行うのと同じ効果があるようです。これは、特定の関数や変数名のヘルプにアクセスする場合にも機能します。多分これはあなたをある程度助けるでしょう。例えば、

ipdb> help(numpy.transpose)
*** No help on (numpy.transpose)

しかし、!help(numpy.transpose) は、numpy.transpose に関する期待されるヘルプ ページを提供します。変数名についても同様に、変数 l があるとします。pdb で「l」と入力するとコードがリストされますが、!l は l の値を出力します。

于 2013-06-14T15:50:31.863 に答える
4

質問に対する正しく、簡単で、クールで正確な答えは、-d フラグを指定して %run マクロを使用することです。

In [4]: run -d myscript.py
NOTE: Enter 'c' at the ipdb>  prompt to continue execution.        
> /cygdrive/c/Users/mycodefolder/myscript.py(4)<module>()
      2                                                            
      3                        
----> 4 a=1                                            
      5 b=2
于 2018-02-20T04:51:04.673 に答える
2

Pyzo IDE には、OP が要求したのと同様の機能があります。デバッグ モードで開始する必要はありません。MATLAB と同様に、コマンドはシェルで実行されます。一部のソース コード行にブレークポイントを設定すると、IDE はそこで実行を停止し、通常の IPython コマンドもデバッグおよび発行できます。

ただし、別のブレークポイントを設定しない限り、ステップインは (まだ?) うまく機能しないようです (つまり、ある行で停止してから別の関数にステップインする)。

それでも、MATLAB から来て、これは私が見つけた最良の解決策のようです。

于 2016-08-14T14:49:57.620 に答える
2

Python 3.2 からinteractは、完全な python/ipython コマンド スペースにアクセスできるコマンドがあります。

于 2018-01-01T19:53:14.013 に答える
1

新しいコードの開発

IPython 内でのデバッグ

  1. Jupyter/IPython セル実行を使用して、実験の反復を高速化します
  2. ステップ スルーには %%debug を使用します

セルの例:

%%debug
...: for n in range(4):
...:    n>2

既存のコードのデバッグ

デバッグ中の IPython

  1. 壊れた単体テストのデバッグ:pytest ... --pdbcls=IPython.terminal.debugger:TerminalPdb --pdb
  2. テスト ケース外でのデバッグ: breakpoint()python -m ipdbなど。
  3. IPython.embed() は、デバッガー内で必要な IPython の完全な機能を提供します。

Python についての考え

私は、MATLAB が適切に行う多くのことを Python がまだ持っておらず、実際にそうすべきであるという OP に同意します。なぜなら、言語のほぼすべてが生産速度よりも開発速度を優先するからです。いつの日か、些細なバグ修正以上のものを CPython に提供することになるでしょう。

https://github.com/ipython/ipython/commit/f042f3fea7560afcb518a1940daa46a72fbcfa68

デバッグを使用して IPython でコマンドを実行することは可能ですか?も参照してください。

于 2020-05-23T21:14:37.580 に答える