SIGMA-SE Math & Tech Library

SIGMA-SE Math & Tech Library


数学と情報技術をテーマに、書籍や教材だけではつかみにくい考え方を具体例とともに簡潔にわかりやすく伝える解説サイトです。
技術の歴史や背景、関連知識の整理、学習のための覚書や要約記事も掲載しています。

Python - 標準デバッガー(Pdb):基本操作とステップ実行

概要

Python標準デバッガーPdbのブレークポイント、ステップ実行、変数確認を整理する。

基本操作を確認した後、合計が期待値と一致しないプログラムを調べる。関数へ渡された値と実際にループへ渡る範囲を比べ、原因を特定して修正後の結果を確認する。

この記事の構成

対象環境と利用上の注意

  • 本文記載時の環境
    Python 3.7以降のbreakpoint()と標準デバッガーPdbを利用する例。
    Python 3.6以前の代替方法も併記。
  • 確認時期
    2026年9月にPythonの公式資料と照合。合計の取りこぼしを調べる比較例はPython 3.12.2で実行確認。
  • 現在そのまま利用できない箇所
    停止位置のパス、行番号、Pdbの表示形式はPythonのバージョンや対象ファイルで変わる。
    出力を固定値として使わず、操作コマンドと処理の流れを参照する。

作業時の注意点

  • stepとnext
    stepは関数の中へ入り、nextは関数呼び出しを一行として進める。
  • 停止位置
    この記事のPython 3.12.2の例では呼び出しの次の実行行で止まる。停止タイミングや表示はバージョンにより異なるため、矢印で示された行を確認する。
  • 変数のスコープ
    現在停止している位置から見える変数だけを確認できる。
  • 消し忘れ
    breakpoint()やpdb.set_trace()を本番コードへ残さない。

実施内容

Pdbの使用例

  • 説明用のサンプルプログラムを作成
    説明用に下記debug_example.pyを作成。

    def add(a, b, c):
        return a + b + c
    
    
    breakpoint()
    step = 0
    step = add(1, 2, 3)
    step = add(4, 5, 6)
    print(step)
    

    breakpoint()はPython 3.7以降で利用でき、既定ではpdb.set_trace()を呼び出す。
    Python 3.6以前では、import pdb; pdb.set_trace()を同じ位置へ記述。

  • debug_example.pyを実行
    以下の表示例ではbreakpoint()の次に実行するstep = 0の行で止まり、入力待ちを表す(Pdb)が表示される。

    $ python debug_example.py
     > /path/to/debug_example.py(6)<module>()
     -> step = 0
     (Pdb)
    
  • nextとstepを使い分けて値を確認
    nは現在の関数内の次の行まで進み、sは呼び出した関数の内部へ入る。
    aで現在の関数の引数を、p <式>で式の評価結果を確認できる。
    以下は操作の流れを抜粋した例となる。

    (Pdb) n       # step = 0を実行し、次の行へ進む
    (Pdb) s       # add(1, 2, 3)の内部へ入る
     --Call--
     > /path/to/debug_example.py(1)add()
     -> def add(a, b, c):
    (Pdb) a       # 現在の関数の引数を表示
    a = 1
    b = 2
    c = 3
    (Pdb) r       # 現在のadd関数がreturnするまで実行
     --Return--
     > /path/to/debug_example.py(2)add()->6
     -> return a + b + c
    (Pdb) n       # 呼び出し元へ戻り、次の行まで進む
    (Pdb) p step
    6
    (Pdb) n       # 2回目のaddは内部へ入らず実行
    (Pdb) p step
    15
    
  • 合計が600になるはずなのに300になる場合を調べる
    次のsubtotal_bug.pyは末尾の要素を取りこぼす確認用プログラムである。100・200・300の合計を600と予想して実行する。

    def subtotal(prices):
        total = 0
        for price in prices[:-1]:
            total += price
        return total
    
    
    prices = [100, 200, 300]
    breakpoint()
    actual = subtotal(prices)
    print(actual)
    

    python subtotal_bug.pyで起動し、actual = subtotal(prices)の行で止まったら入力データを調べる。次は停止位置の表示を一部省いた操作例である。Pdbのコマンドにコメントを付けず順に入力する。

    (Pdb) p prices
    [100, 200, 300]
    (Pdb) s
    (Pdb) a
    prices = [100, 200, 300]
    (Pdb) p prices[:-1]
    [100, 200]
    (Pdb) r
    --Return--
    > /path/to/subtotal_bug.py(5)subtotal()->300
    -> return total
    (Pdb) n
    (Pdb) p actual
    300
    (Pdb) c
    300
    

    呼び出し元のlistにも関数の引数にも300があるため、受け渡し時には失われていない。prices[:-1]は末尾を除くスライスなので、ループに渡った段階で300が外れている。rで戻り値が300であることを確認できる。

    関数を次のように直し、ブレークポイントを外して再実行する。

    def subtotal(prices):
        total = 0
        for price in prices:
            total += price
        return total
    
    
    for prices in ([100, 200, 300], [300], []):
        print(subtotal(prices))
    
    600
    300
    0
    

    複数要素に加え、1要素と空のlistでも期待値を確認する。Pdbでは「入力は正しいか」「どの式で期待とずれたか」を順に調べ、修正後はデバッガーなしでも結果を再現できる状態にする。

Pdbの基本操作方法

以下、よく使用するPdbコマンド。

  • [s] or [step]
    現在行を実行し、呼び出した関数の内部を含む、次に停止可能な位置で止まる。

  • [n] or [next]
    現在行を実行し、現在の関数内の次の行、または現在の関数が戻る位置で止まる。
    呼び出した関数の内部では停止しない。

  • [r] or [return]
    現在の関数が戻るまで実行。

  • [c] or [continue]
    次回のブレークポイントまで停止せず実行。

  • [l] or [list]
    現在停止行の前後のソースを表示。

  • [a] or [args]
    現在停止している関数の引数を表示。

  • [p <式>]
    現在のコンテキストで式を評価し、結果を表示。

  • [q] or [quit]
    デバッグ中のプログラムを終了。

まとめ

  • Pdbでは停止位置の入力や途中結果を調べ、期待値との差が最初に現れる式を絞り込める。
  • stepは関数へ入り、nextは現在の関数内を進める。argsで引数、pで式、returnで戻り値を確認する。
  • 原因を修正した後はブレークポイントを外し、通常の入力と境界となる入力で結果を再確認する。

参考文献

この記事を共有
Xで共有 Facebookで共有 LINEで共有



Copyright SIGMA-SE All Rights Reserved.
s-hama@sigma-se.jp