2
def dummyFunction(context, data):
    ...
    doing something
    ...
    return something

正常に実行されるスクリプトがありますが、1〜2個の特定の変数をトレースしたいのですが、たとえば、すべての変更と履歴、およびに関連するステートメントをトレースバックしたい場合、dataPythonで何ができるでしょうか?

Pythonには、特定の変数に関連するすべての手順を展開するのに役立つ組み込み関数がありますか?変数の名前だけを知っているPythonで何を見つけることができますか?

本当に衒学者になるために、私はこのラベルについて可能なすべての情報を知りたいのですが、本当に重要なものは次のとおりです。

  • この変数の内容と、実行中に変更された方法と変更の有無
  • 宣言されている場所
4

4 に答える 4

2

あなたが尋ねていることの一部(実行中にどのようにそしてそれが変更されたかどうか)は、バックインタイムデバッガーによってのみ答えることができます。私の知る限り、いくつかは存在しますが、全体として、それは現在の研究分野であり、取り組むべき非常に複雑な問題です。過去のデバッグについての興味深い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 )、関数がその引数で呼び出された理由を見つけます。呼び出し元の関数が取得した引数を確認してください。llocals()

必要に応じて、スタックを上( u)または下( )に移動します。dこれは命令ポインタをまったく動かさず、呼び出しスタックを表すタマネギの層を剥がしているだけです。

ある時点で、気になることがコードの特定の行で発生していることがわかりますが、それはすでに過ぎています(すでに実行されています)。それがフォローしたいリードであると確信したら、現在のpdbセッション(q)を終了し、ブレークポイントを削除して、興味深いコード行の前に戦略的に配置された新しいブレークポイントを設定します。

知りたいことがわかるまで繰り返します。

いずれかの関数が何百回も呼び出されたが、特定のケースにのみ関心がある場合は、条件が満たされたときにのみブレークポイントがトリガーされるようにコードを変更します。例えば:

if 'interesting' in data.keys():
    import pdb; pdb.set_trace()

このパターンに従うと、自分や他の人のコードを理解してデバッグするのに長い道のりがかかります。そして覚えておいてください:それはただのPythonです;-)

于 2012-09-10T20:06:37.567 に答える
1

変数の内容に関する情報を取得するには、dir(obj)関数を使用できます。

ここのように:

class B(object):
    a = 0
    b = 1

b = B()
dir(b)

それはあなたに与えるでしょう

['__class__',
 '__delattr__',
 '__dict__',
 '__doc__',
 '__format__',
 '__getattribute__',
 '__hash__',
'__init__',
 '__module__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 'a',
 'b']

標準ライブラリ内にあるinspectモジュールには、オブジェクトに関する情報を収集するための優れたツールも多数あります。

于 2012-09-10T19:04:02.787 に答える
0

コードでpdbを使用する方法の詳細については、この投稿を参照してください。Pythonデバッガーは、本当に必要なことを実現するための最良の方法の1つです。

http://greeennotebook.com/2010/06/using-the-python-debugger-pdb/

于 2012-09-10T18:51:40.250 に答える
0

コードの単体テストを作成し(まだ作成していない場合)、実際のオブジェクトを渡す代わりに、たとえばMockライブラリを使用してモックオブジェクトを渡す方がよいと思います。次に、そのオブジェクトへの呼び出しが行われたかどうかを確認できます。

Pythonの変数名は単なるラベルであることに注意してください。通常、アプリケーションをデバッグするときにこれがはるかに理にかなっているため、参照渡し/値渡しなどについて学ぶ方がよいでしょう。

于 2012-09-10T18:40:48.820 に答える