あなたが尋ねていることの一部(実行中にどのようにそしてそれが変更されたかどうか)は、バックインタイムデバッガーによってのみ答えることができます。私の知る限り、いくつかは存在しますが、全体として、それは現在の研究分野であり、取り組むべき非常に複雑な問題です。過去のデバッグについての興味深いGoogleTechTalkがあります。しかし、Pythonですぐに利用できるものがあるかどうかはわかりません。
幸いなことに、これが必要になることはめったにありません。
あなたの例では、私は次のようにデバッグにアプローチします:
その関数定義の最初の行にブレークポイントを設定します。
def dummyFunction(context, data):
import pdb; pdb.set_trace()
これにより、その関数が最初に呼び出されたとき(および以降のすべての呼び出しで)にpdbが起動します。
これを確認するl
には、(小文字のL)と入力します。これにより、現在使用しているコード行とその周囲のコンテキストが一覧表示されます。
次に、と入力data
しての内容を調べdata
ます。通常のインタラクティブインタプリタと同じように、オブジェクトにアクセスして検査できます。
ここで、入力w
して呼び出しスタックを確認します。現在(dummyFunction
)にいる呼び出しは一番下にあり、それを呼び出した呼び出しは最後から2番目の行にあります。
今、あなたはそれが現在どのよう になったのか知りたいですdata
。したがって、呼び出しスタックを上下に移動して、その関数がその引数で呼び出された理由を知ることができます。
u
呼び出しスタックで1回上に移動するように入力します。これで、を呼び出す関数が表示され、そのdummyFunction(context, data)
関数のローカルスコープで変数を検査できるようになります。したがって、もう一度入力してコードを表示し、呼び出しの数行前に何が起こるかを調べます。何か条件はありますか?彼らはどのような表現に依存していますか?これらの式を評価し、ローカル変数を調べて(try )、関数がその引数で呼び出された理由を見つけます。呼び出し元の関数が取得した引数を確認してください。l
locals()
必要に応じて、スタックを上( u
)または下( )に移動します。d
これは命令ポインタをまったく動かさず、呼び出しスタックを表すタマネギの層を剥がしているだけです。
ある時点で、気になることがコードの特定の行で発生していることがわかりますが、それはすでに過ぎています(すでに実行されています)。それがフォローしたいリードであると確信したら、現在のpdb
セッション(q
)を終了し、ブレークポイントを削除して、興味深いコード行の前に戦略的に配置された新しいブレークポイントを設定します。
知りたいことがわかるまで繰り返します。
いずれかの関数が何百回も呼び出されたが、特定のケースにのみ関心がある場合は、条件が満たされたときにのみブレークポイントがトリガーされるようにコードを変更します。例えば:
if 'interesting' in data.keys():
import pdb; pdb.set_trace()
このパターンに従うと、自分や他の人のコードを理解してデバッグするのに長い道のりがかかります。そして覚えておいてください:それはただのPythonです;-)