Pythonのデバッグ方法とデバッガの使い方

Top

デバッグ方法

ソースコードをよく見る(観察する)

1行ごとに自分がCPUになったのつもりで変数内容を書き止め、流れをシミュレーションする。

print文を使う

print文をソースコードに書き加えて変数内容を確認したり、 関数の始め、終わり、ループ内に書いて流れを確認します。 ※ loggingパッケージを使う手もあります。基本 logging チュートリアル

デバッグツール(デバッガ)を使う

しかしprint文は書くのが大変で確認後は削除しますので危険です、 なのでデバッグツールをご紹介します。

デバッグには便利なツールがあります

それは、デバッガです

Python標準でついています、pdbと呼ばれています。
起動は、pdbモジュールを呼出せばOKですよ!
その他 色々ありますが、お薦めはこちら…サイト推薦です チェックしてね

py -m pdb test.py(ターゲットファイル名)

Pythonランチャー
ここのサンプルでの注意点ですが…

Windows版のPythonでは、python コマンドを使うより、
Pythonランチャー py がおすすめです。通常、Python をコマンドラインから実行するときには、
Pythonをインストールしたディレクトリを環境変数というシステム設定に記録する必要がありますが、
py は、設定をしなくとも実行できます。

https://www.python.jp/install/windows/py_launcher.htmlの引用

実際にデバッグする

デバッガコマンド

コマンドは沢山ありますが すべて覚える必要はありません、以下で十分です。
(スキルアップしたい時にドキュメントを見ましょう)

コマンド説明
cont実行継続 (ブレークポイントで止まる)c(省略)
quitデバッガ終了q(省略)
step1行実行(関数内に入る)s(省略)
next1行実行n(省略)
breakブレークポイントの設定、実行継続(cont)で設定すると止まるb 10(10行目で止まる)
listソースコードを表示l(省略), llだと全体
p変数内容の表示p ix,data
※これらは、頭一文字だけの省略可能 ※詳しく知りたい方は 公式 (https://docs.python.org/) のデバッガコマンドを参照してみて下さい

解説
1行毎に実行を進めたい場合は「next」を使います、続けて「next」の場合はEnterキーだけでも大丈夫です、
「next」は関数内部に入って処理できません、関数呼出の前で「step」して処理を移します。

コードが最後の方にある場合は、「next」では大変です、指定行まで処理を実行させてしまってから「next」しましょう、
「break 行番号」で行を指定後に「cont」で実行をさせると
指定行まで処理が行われます。

デバッガの起動と終了、そしてコード表示

起動と終了を見てみましょう

起動して終了は基本だけど、コード表示もしてみましょう!
最初に準備、メモ帳等でソースコードを作成します。
ファイル名は「test10.py」にしましたが、拡張子は決まりで「.py」です。
※このコードには説明の為にバグが含まれています
#-------------------------------------------------------------------
#    ソースコード1
#------------------------------------------------------------------
print("こんにちは")
print("すいませんが")

namae = "小林さん"
old       = 25
print( namae + old + "才でしたよね")
デバッガを起動します。 パイソンを起動時に、pdbモジュールを指定(-m モジュール名)するとデバッガが起動されます。 py -m pdb ファイル名(test10.py) python -m pdb ファイル名 pdb ファイル名 ※こちらも可能 起動されると、 1行目(先頭に)はファイル名(行番号)があり、 2行目(先頭にー>)は実行前のPythonコードが表示され、 最後にデバッガのプロンプト(pdb)が表示されます。 この辺に慣れると、デバッグが楽しくなるかも!
C:\Users\kobay>py -m pdb test10.py
> c:\users\kobay\test10.py(2)()
-> print("こんにちは")
(Pdb)
まとめると以下の様になります。(省略系も使ってみて下さい)

C:\Users\kobay>py -m pdb test10.py
> c:\users\kobay\test10.py(2)()
-> print("こんにちは")
(Pdb)
(Pdb)
(Pdb)
(Pdb) list
  1
  2  -> print("こんにちは")
  3     print("すいませんが")
  4
  5     namae = "小林さん"
  6     old       = 25
  7
  8     print( namae + old + "才でしたよね")
[EOF]
(Pdb)
[EOF]
(Pdb)
[EOF]
(Pdb) quit

C:\Users\kobay>
  1. 起動はコマンドプロンプトから
  2.  py -m pdb test10.py でデバッガ起動  py test10.py はプログラム実行のみ  
  3. コード表示は、 list (省略はl)
  4. 行番号の右の「ー>」実行前のコード
  5. デバッガ終了は、quit (省略はq)

起動方法には別方法もあります! 以下の一行をソースコードに書き足します、 書き足した行からデバッグモードになりますよ。 (pdbプロンプトが表示されます) import pdb; pdb.set_trace() ※リスタートは出来ないみたいですので、デバッガを立ち上げた方がはやいかも?

クラッシュした場合(落ちた場合) コマンドラインからPython実行(ファイル名指定なし)をして、 以下をimportすると、 Pythonデバッガがエラー箇所から立ち上がる。 import pdb import 落ちたソースファイル pdb.pm()

普通に実行したらエラー


C:\Users\kobay>py test10.py
こんにちは
すいませんが
Traceback (most recent call last):
  File "test10.py", line 6, in 
    print( namae + old + "才でしたよね")
TypeError: can only concatenate str (not "int") to str

エラー発生なのでデバッガを起動します。 (前述を参考して下さい)
    (Pdb) list
      1  -> print("こんにちは")
      2     print("すいませんが")
      3
      4     namae = "小林さん"
      5     old       = 25
      6     print( namae + old + "才でしたよね")
    [EOF]
    (Pdb) 
「n」Enterと入力すると1行だけ実行されて、(Pdb)のプロンプトが表示されます。
行の先頭の 「->」は実行前の行になりますので注意して下さいね!

プロンプトが表示されたら再度コマンドの入力ができます。
どんどんEnterだけ入力して実行していきます、すると…



(Pdb) n
こんにちは
> c:\users\kobay\test10.py(2)()
-> print("すいませんが")
(Pdb)

    
(Pdb)
すいませんが
> c:\users\kobay\test10.py(4)()
-> namae = "小林さん"
(Pdb)

(Pdb)
> c:\users\kobay\test10.py(6)()
-> print( namae + old + "才でしたよね")
(Pdb)
TypeError: can only concatenate str (not "int") to str
> c:\users\kobay\test10.py(6)()
-> print( namae + old + "才でしたよね")
(Pdb)
このようなエラーが発生しました。
(エラー発生時には、同じ箇所を示しているので戸惑いますが…)

    TypeError: can only concatenate str (not "int") to str

データ型を調べてみましょう、Python言語のtypeを使います。

(Pdb) type( old )
class 'int'
(Pdb) type( namae )
class 'str'
どうやら、oldは int型ですね!
エラーメッセージ道理 int型は結合できないですよね!

ソースの修正前に、修正内容を検証してみる

ブレークポイントの使い方、変数の書換えを説明します

バグが判明したので修正ですが、折角なのでデバッガを利用して修正内容を確認してみましょう。

修正してまたエラーって 結構やっちゃうますよね、
やっとのバグ発見で気が緩むんですかね。

デバッガでは、Python言語そのものが使えます、
つまり、デバッグ途中でコードの書換えができるのですね、
すばらしではありませんか!

変数oldがint型なのでstr型にします、エラー発生の前に変換してみましょう。

デバッグを開始してエラー発生前まで実行させます、
「list」で止めたい行を見つけてブレークポイントを設定します。

設定は、「break 行番号」
「cont」でブレークポイントまで実行させて、修正内容を入力します。

変数oldを文字列型に変換して修正完了ですね、
型も試しに見てみましょう。

「変数名=値」で変数内容を変更します(もちろんソースコードには反映されません)

    (Pdb) old= str(old)
    (Pdb) type(old)
    

恐るおそる、「next」でエラー発生行を実行すると、めでたしめでたし!
できました。

    (Pdb) next
    小林さん25才でしたよね
    --Return--
    > c:\users\kobay\test10.py(6)()->None
    -> print( namae + old + "才でしたよね")
    (Pdb)

最後の「--Return--」は何か心配ですが、
メインモジュールが終了(return)してデバッガに戻るって感じですかね!
分かりずらいですね!

    (Pdb) list
      1  -> print("こんにちは")
      2     print("すいませんが")
      3
      4     namae = "小林さん"
      5     old       = 25
      6     print( namae + old + "才でしたよね")
    [EOF]
    (Pdb) break 6
    Breakpoint 1 at c:\users\kobay\test10.py:6
    (Pdb) cont
    こんにちは
    すいませんが
    > c:\users\kobay\test10.py(6)()
    -> print( namae + old + "才でしたよね")
    (Pdb) old= str(old)
    (Pdb) type(old)
    <class 'str'>
    (Pdb) next
    小林さん25才でしたよね
    --Return--
    > c:\users\kobay\test10.py(6)()->None
    -> print( namae + old + "才でしたよね")



pdbは、使え熟せるとかなり重宝だと感じました。

linux, unixのviコマンドののりですかね、キーボードでパッパ、パッパという感じがしますね、
一度は挑戦してみて下さいね!



©2022 Kenji Kobayashi YouTube