PySnooper を使って Python スクリプトをデバッグする
PySnooper を使うと print() や pdb を使わずにデバッグを行うことが出来ます。 PySnooper のページには PySnooper is a poor man's debugger. と書かれていました。 PySnooper の使い方をメモしておきます。 尚、ソースコードは cool-RR / PySnooper にありました。
ソースコードの行数¶
単純に行数だけ数えた場合、現時点では約 800 行のようです。 熟読出来ていませんが、中核となる実装は tracer.py に集中しているように見えました。
1 2 3 4 5 6 7 8 9 | |
インストール¶
pip でインストールします。
1 | |
関数にデコレータを指定してデバッグする¶
デバッグしたい関数に @pysnooper.snoop() というデコレータをつけることで、該当の関数全体をデバッグ出来ます。
1 2 3 4 5 6 7 8 9 | |
実行結果は以下の通りです。 実行の過程、変数への代入などが標準出力へ書き出されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
デバッグしたい部分を with ブロックで囲む¶
関数全体では無く、部分的にデバッグしたい場合は該当箇所を with pysnooper.snoop(): ブロックで囲みます。
1 2 3 4 5 6 7 8 9 | |
実行結果は以下の通りです。 with ブロックで囲まれていなくても変数への代入はデバッグ表示されていました。 まだソースコードを読めていないので、この辺りの細かい挙動は掴めていません…
1 2 3 4 5 6 7 8 | |
出力をファイルに保存する¶
PySnooper の引数にファイル名を指定するとデバッグ結果を (標準出力では無く) 指定したファイルへ書き出します。
1 2 3 4 5 6 7 8 9 | |
実際にスクリプトを実行しても、標準出力には何も表示されなくなりました。
1 2 | |
指定した名前のファイルが作成されており、デバッグ出力されていました。 尚、PySnooper は既存のファイル名を指定した場合、ログファイルを追記するようです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
デバッグ用コードを残したまま、デバッグ表示の有効/無効を切り替える¶
PySnooper のデバッグ用コードの有無に関わらず、デバッグ表示の有効 / 無効を切り替えるには PYSNOOPER_DISABLED 環境変数を使います。 この機能は activate / desactivate pysnooper ? #127 という Issue で議論され、実装されたもののようです。
cool-RR commented on 5 Jun 2019 @alexmojaki Great, thanks for the input!
@yvonhubert If you or anyone else would like to implement, go ahead. The environment variable name should be PYSNOOPER_DISABLED and if it has a non-empty value, then PySnooper is in no-op mode, i.e. any decorated functions will just be the original functions and the context manager will not do anything. Tests should be added.
PySnooper の tracer.py では以下のように定義されているようです。 PYSNOOPER_DISABLED 環境変数の定義があれば、DISABLED フラグを有効化するようです。 デバッグした結果を出力する際、この DISABLED フラグの論理値を見て、「出力する or しない」を判定しているようです。
1 | |
上記コードの通り、PYSNOOPER_DISABLED 環境変数の中身は確認しておらず、「定義されているか、否か」しか確認していません。 但し、bash で環境変数を export する際に値が未定義だと環境変数が定義されない為、とりあえず適当に True という値を設定してみました (a でも False でも、何を定義しても同じ動作になります)。
1 | |
これでソースコード自体は変更せずに、デバッグ表示を無効化することが出来ました。
1 2 3 4 5 | |
尚、上述の Issus でも「有効/無効を切り替えるのはコンフィグでは無く環境変数で」という方針になったようで、実際に実装上もそのようになっています。 従って「外部のコンフィグでデバッグ表示の有効 / 無効を切り替える」ということは出来ないようです。