コードのデバッグ技術

PythonPythonBeginner
今すぐ練習

This tutorial is from open-source community. Access the source code

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

コードは決して完璧ではありません。バグは常にあります。コードのデバッグは学ぶ必要のあるスキルです。

デバッグのヒント

さて、あなたのプログラムはクラッシュしてしまいました...

$ python3 blah.py
Traceback (most recent call last):
  File "blah.py", line 13, in?
    foo()
  File "blah.py", line 10, in foo
    bar()
  File "blah.py", line 7, in bar
    spam()
  File "blah.py", 4, in spam
    line x.append(3)
AttributeError: 'int' object has no attribute 'append'

これでどうしたらいいのでしょうか?

トレースバックの読み方

最後の行がクラッシュの具体的な原因です。

$ python3 blah.py
Traceback (most recent call last):
  File "blah.py", line 13, in?
    foo()
  File "blah.py", line 10, in foo
    bar()
  File "blah.py", line 7, in bar
    spam()
  File "blah.py", 4, in spam
    line x.append(3)
## クラッシュの原因
AttributeError: 'int' object has no attribute 'append'

ただし、読んだり理解したりするのは必ずしも簡単ではありません。

プロのコツ:トレースバック全体をGoogleに貼り付けましょう。

REPL の使用方法

スクリプトを実行する際に、オプション -i を使って Python を実行中に維持します。

$ python3 -i blah.py
Traceback (most recent call last):
  File "blah.py", line 13, in?
    foo()
  File "blah.py", line 10, in foo
    bar()
  File "blah.py", line 7, in bar
    spam()
  File "blah.py", 4, in spam
    line x.append(3)
AttributeError: 'int' object has no attribute 'append'
>>>

これによりインタプリタの状態が保持されます。つまり、クラッシュ後に調べることができます。変数の値やその他の状態を確認できます。

print を使ったデバッグ

print() によるデバッグは非常に一般的です。

ヒント:repr() を使うことを確認しましょう。

def spam(x):
    print('DEBUG:', repr(x))
 ...

repr() は値の正確な表現を表示します。見やすい印刷出力ではありません。

>>> from decimal import Decimal
>>> x = Decimal('3.4')
## `repr` なし
>>> print(x)
3.4
## `repr` あり
>>> print(repr(x))
Decimal('3.4')
>>>

Python デバッガ

プログラム内でデバッガを手動で起動することができます。

def some_function():
 ...
    breakpoint()      ## デバッガに入る (Python 3.7以降)
 ...

これにより、breakpoint() の呼び出し箇所でデバッガが起動します。

以前の Python バージョンでは、このようにしていました。他のデバッグガイドでこれが言及されることもあります。

import pdb
...
pdb.set_trace()       ## `breakpoint()` の代わり
...

デバッガの下で実行する

デバッガの下で、全体のプログラムを実行することもできます。

$ python3 -m pdb someprogram.py

最初の文の前に自動的にデバッガに入ります。ブレークポイントを設定したり、設定を変更したりすることができます。

一般的なデバッガコマンド:

(Pdb) help            ## ヘルプを取得する
(Pdb) w(here)         ## スタックトレースを表示する
(Pdb) d(own)          ## 1つ下のスタックレベルに移動する
(Pdb) u(p)            ## 1つ上のスタックレベルに移動する
(Pdb) b(reak) loc     ## ブレークポイントを設定する
(Pdb) s(tep)          ## 1つの命令を実行する
(Pdb) c(ontinue)      ## 実行を続ける
(Pdb) l(ist)          ## ソースコードを表示する
(Pdb) a(rgs)          ## 現在の関数の引数を表示する
(Pdb)!statement      ## 文を実行する

ブレークポイントの位置は、次のいずれかです。

(Pdb) b 45            ## 現在のファイルの45行目
(Pdb) b file.py:45    ## file.pyの45行目
(Pdb) b foo           ## 現在のファイルのfoo()関数
(Pdb) b module.foo    ## モジュール内のfoo()関数

演習8.4:バグ?どんなバグ?

動作します。リリースしましょう!

まとめ

おめでとうございます!あなたはデバッグの実験を完了しました。あなたのスキルを向上させるために、LabExでさらに多くの実験を練習することができます。