以下の記事を訳していた時に気づきました。Python debugger(pdb)を使うことで、例外発生時の問題特定が容易になります。
翻訳済みサンプルノートブックはこちらです。
要件
Databricksランタイム11.2以降が必要となります。
サンプルノートブックのウォークスルー
Databricksノートブックにおけるpdbの使い方のサンプルを示します。
- 最後の例外からデバッグするには
%debug
を使います。これは、予期しないエラーに遭遇し、原因をデバッグする際に役立ちます(pdb.pm()
と似ています)。 - 例外後(しかし、プログラム終了前)にインタラクティブなデバッガーを自動で起動するには
%pdb on
を使います。
これらのコマンドを使う際には、他のセルを実行する前にデバッガーの使用を停止する必要があることに注意してください。デバッガーを終了する方法はいくつかあります。
- 実行中のセルを終了するために
c
あるいはcontinue
を入力 - エラーをスローしコード実行を停止するために
exit
を入力 - 出力ボックスの隣にある
Cancel
をクリックしてコマンドをキャンセル
%debug
: 事後のデバッグ
Databricksノートブックで%debug
を使うには:
- 例外が起きるまでノートブックのコマンドを実行します。
- 新規セルで
%debug
を実行します。セルの出力エリアでデバッガーが動作を始めます。 - 変数を調査するには、入力フィールドに変数名を入力し Enter を押します。
- 以下のコマンドを用いることで、変数の調査の様に、コンテキストを切り替えたり他のデバッガータスクを行うことができます。デバッガーの完全なコマンドの一覧に関しては、pdb documentationをご覧ください。文字列を入力し、 Enter を押します。
-
n
: 次の行 -
u
: 現在のスタックフレームを抜けて1レベル上に移動 -
d
: 現在のスタックフレームを抜けて1レベル下に移動
-
- このノートブックの最初のセルで説明した方法のいずれかでデバッガーを抜けます。
Python
class ComplexSystem1:
def getAccuracy(self, correct, total):
# ...
accuracy = correct / total
# ...
return accuracy
class UserTest:
def __init__(self, system, correct, total):
self.system = system
self.correct = correct
self.total = 0 # 間違った合計を設定しています!
def printScore(self):
print(f"You're score is: {self.system.getAccuracy(self.correct, self.total)}")
test = UserTest(
system = ComplexSystem1(),
correct = 10,
total = 100
)
test.printScore()
デバッガーを起動します。
%debug
self.total
を確認すると0
であることがわかるので、これが原因であることが判明しました。
%pdb on
: 事前のデバッグ
Databricksノートブックで%pdb on
を使うには:
- ノートブックの最初のセルで
%pdb on
を実行して自動pdbをオンにします。 - 例外が起きるまでノートブックでコマンドを実行します。インタラクティブなデバッガーが起動します。
- 変数を調査するには、入力フィールドに変数名を入力し Enter を押します。
- 以下のコマンドを用いることで、変数の調査の様に、コンテキストを切り替えたり他のデバッガータスクを行うことができます。デバッガーの完全なコマンドの一覧に関しては、pdb documentationをご覧ください。文字列を入力し、 Enter を押します。
-
n
: 次の行 -
u
: 現在のスタックフレームを抜けて1レベル上に移動 -
d
: 現在のスタックフレームを抜けて1レベル下に移動
-
- このノートブックの最初のセルで説明した方法のいずれかでデバッガーを抜けます。
pdbをオンにします。
%pdb on
Python
class ComplexSystem2:
def getAccuracy(self, correct, total):
# ...
accuracy = correct / total
# ...
return accuracy
system = ComplexSystem2()
## テストのカバレッジ
print("Tests")
print(system.getAccuracy(10, 100) == 0.1)
print(system.getAccuracy(10, 0), 0)