閉じる

VSCode不要: Python標準のbreakpoint()で手早くバグ特定

Python 3.7以降には、追加インストールなしで使える標準の対話型デバッガ起動関数が用意されています。

それがbreakpoint()です。

エディタやIDEの設定に時間をかけず、ターミナルからすぐに停止、変数確認、再開ができます。

print()デバッグを卒業したい初心者の方が最初に身につけるのに最適なアプローチを、最短手順と実例で丁寧に解説します。

breakpoint()とは(Python 3.7+標準のデバッグ機能)

インストール不要・VSCode不要

breakpoint()はPython 3.7以降に標準搭載されたデバッガ起動用の関数です。

呼び出し時にsys.breakpointhookを介してデバッガを起動し、既定ではpdb(Python標準のデバッガ)が立ち上がります。

追加インストールやVSCodeなどのIDE設定は不要で、WindowsやmacOS、Linuxのターミナルからそのまま使えます。

内部的にはbreakpoint()sys.breakpointhook()を呼び、環境変数PYTHONBREAKPOINTの指定があればそれに従い、無指定ならpdb.set_trace()が使われます。

これにより、後述の通り別のデバッガに切り替えることもできます。

print()デバッグからの卒業に最適

print()で値を出力して原因を探る手法は、行が増えるほど管理が難しくなり、確認したい瞬間に状態を取り逃がしがちです。

breakpoint()なら、興味のある行で実行を一時停止し、pコマンドでその場の変数を調べたり、snで1行ずつ実行を追えます。

不要になったら1行削除するだけなので、ログの掃除も最小限です。

以下は対比のイメージです。

Python
# 悪い例: print()が増殖して管理がつらい
def calc_total(prices):
    total = 0
    for i, p in enumerate(prices):
        print("DEBUG i:", i, "p:", p)  # その場しのぎの出力
        total += p
    print("DEBUG total:", total)
    return total
Python
# 良い例: 確認したい行で止めるだけ
def calc_total(prices):
    total = 0
    for i, p in enumerate(prices):
        total += p
    breakpoint()  # ここで止めて、i/p/totalを対話的に調べる
    return total

実行時にpdbが自動起動

デバッガは実行時に自動起動し、その場でプログラムの「状態」を対話的に確認できます

ファイル名や行番号、現在行の内容が表示され、続けるか、1行ずつ進めるか、関数の中に入るかなどを選べます。

これにより、原因箇所に素早く迫れます。

breakpoint()の使い方(最短手順)

ここでは最短で動かすための、最少ステップでの手順を示します。

停止させたい行にbreakpoint()を置く

次のミニアプリは割引率の解釈ミス(10を10%として渡しているが、関数は0.10を想定)を、breakpoint()で見抜く例です。

Python
# ファイル名: shop.py
# 目的: 割引計算のバグをbreakpoint()で手早く特定する

def subtotal(prices):
    return sum(prices)

def apply_discount(total, rate):
    """rateは0.10のような小数を想定しているが、呼び出し側が10を渡してしまうバグ"""
    return total - total * rate  # 10を渡すと total - total*10 になり大幅なマイナス

def checkout(prices, rate):
    total = subtotal(prices)
    breakpoint()  # ここで停止して total と rate を確認してみる
    return apply_discount(total, rate)

if __name__ == "__main__":
    prices = [1200, 800, 600]
    rate = 10  # 10%のつもりで10を渡してしまった(本来は0.10)
    print(checkout(prices, rate))

スクリプトを実行して停止を確認

ターミナルから通常通り実行すると、breakpoint()で停止し、pdbが起動します。

text
$ python shop.py
> .../shop.py(13)checkout()
-> return apply_discount(total, rate)
(Pdb)

変数や状態を確認

止まった時点のローカル変数や式の評価は、pコマンドで確認できます。

現在位置の周辺コードはlで一覧できます。

text
(Pdb) p total
2600
(Pdb) p rate
10
(Pdb) l
  8     def checkout(prices, rate):
  9         total = subtotal(prices)
 10         breakpoint()  # ここで停止して total と rate を確認してみる
 11         return apply_discount(total, rate)
 12
(Pdb)

この時点でrateが10であることが判明し、関数が期待する0.10とは桁が違うと気付けます。

そのまま再開・終了の基本操作

原因が分かったら、cで続行、qで終了できます。

text
(Pdb) c
-20800

本番実行で停止するとサービス影響が出るため、breakpointは開発中に限定するか、後述のPYTHONBREAKPOINTで無効化しましょう。

pdbの基本コマンド(初心者向け最小セット)

<p>最初は次の6つだけ覚えれば十分です。

すべて小文字1文字で使え、直感的に動かせます。

</p>

次の行へ進む(n)

現在の関数の次の行まで実行します。

関数呼び出しは「中に入らず」通過します。

text
(Pdb) n
> .../shop.py(11)checkout()
-> return apply_discount(total, rate)

関数に入る(s)

呼び出し先の関数に入って、その中の最初の行で停止します。

細かく内部を追いたい時に使います。

text
(Pdb) s
> .../shop.py(6)apply_discount()
-> return total - total * rate

続けて実行(c)

次のブレークポイントまで、またはプログラム終了まで一気に実行します。

停止したい箇所にbreakpoint()が複数ある場合にも便利です。

text
(Pdb) c
-20800

変数を見る(p 変数名)

変数名や式を評価して表示します。

ppで整形表示も可能です。

text
(Pdb) p rate
10
(Pdb) p total * rate
26000
(Pdb) pp {"total": total, "rate": rate}
{'total': 2600, 'rate': 10}

現在位置を一覧表示(l)

現在行の周辺コードを表示します。

もう一度lを打つと次の範囲が表示されます。

text
(Pdb) l
  8     def checkout(prices, rate):
  9         total = subtotal(prices)
 10         breakpoint()
 11         return apply_discount(total, rate)

中断して終了(q)

デバッガを即終了し、プログラムも中断します。

実行途中で抜けたい場合に使います。

text
(Pdb) q

以下に最小セットの早見表を載せます。

コマンド動作の概要補足
n次の行へ進む呼び出し先には入らない
s関数に入る呼び出し先の最初の行で停止
c続けて実行次のbreakpointか終了まで進む
p expr変数や式を表示ppで整形表示
lソース表示再実行で続きが見られる
q中断して終了即座に抜ける

環境変数PYTHONBREAKPOINTの活用

PYTHONBREAKPOINTはbreakpoint()の挙動を外部から切り替えるためのスイッチです。

インストールなしの標準デバッガ利用から、サードパーティ製への置き換え、一時無効化まで柔軟に制御できます。

別デバッガに切り替え(ipdbなど)

よりリッチなデバッガipdbに切り替える例です。

ipdb自体は別途インストールが必要ですが、コード側はbreakpoint()のままでOKです。

Shell
# インストール
pip install ipdb

# macOS/Linux (一時的にこの実行だけ)
PYTHONBREAKPOINT=ipdb.set_trace python shop.py

# Windows PowerShell
$env:PYTHONBREAKPOINT="ipdb.set_trace"; python .\shop.py

# Windows CMD
set PYTHONBREAKPOINT=ipdb.set_trace && python shop.py

一時的に無効化(PYTHONBREAKPOINT=0)

CIや本番相当の実行では、デバッガで止まると困ります。

0を指定するとbreakpoint()は何もしません

Shell
# macOS/Linux
PYTHONBREAKPOINT=0 python shop.py

# Windows PowerShell
$env:PYTHONBREAKPOINT="0"; python .\shop.py

# Windows CMD
set PYTHONBREAKPOINT=0 && python shop.py

開発と本番で挙動を切り替える

運用の基本は開発では有効、本番では無効です。

以下のように、環境変数を使い分ける運用をチーム標準にすると安全です。

  • 開発マシン: 既定のpdbまたはipdbを使う
  • CIや本番: PYTHONBREAKPOINT=0で停止しないようにする
  • Dockerやプロセスマネージャと併用する場合も、環境変数により横断的に制御できる

本番ビルドにbreakpoint()を残しても、環境変数で無効化してあれば停止しません

ただし、将来の混乱を避けるため、不要になったbreakpointは最終的に削除するのが望ましいです。

環境変数の設定例(Windows/macOS/Linux)

OSごとの代表的な設定方法をまとめます。

永続化したい場合は各OSのシェル初期化ファイルやシステム環境変数に登録します。

Shell
# macOS/Linux: 一時的にこの実行だけ(前置き)
PYTHONBREAKPOINT=ipdb.set_trace python shop.py

# macOS/Linux: セッション中ずっと有効
export PYTHONBREAKPOINT=ipdb.set_trace
python shop.py
PowerShell
# Windows PowerShell: セッション内で有効
$env:PYTHONBREAKPOINT = "ipdb.set_trace"
python .\shop.py

# 解除
Remove-Item Env:PYTHONBREAKPOINT
Batch File
:: Windows CMD: 1回の実行だけ有効
set PYTHONBREAKPOINT=ipdb.set_trace && python shop.py

:: セッションに残したい場合
set PYTHONBREAKPOINT=ipdb.set_trace
python shop.py
ポイント

0で無効、モジュール名.関数名でデバッガ切り替え、無指定なら標準のpdbが起動します。

まとめ

breakpoint()はPython 3.7+で使える、最速かつ標準的なデバッグの入り口です。

任意の行で実行を止め、pで変数を確認し、nsで追い、cで再開するだけで、print()デバッグでは見逃しがちな「その瞬間の状態」を確実に掴めます。

さらにPYTHONBREAKPOINTにより、開発では有効、本番では無効といった運用切り替えやipdbへの置き換えも簡単です。

まずは小さなスクリプトでbreakpoint()を1行差し込み、上で紹介した6コマンド(n, s, c, p, l, q)を試してみてください。

「VSCode不要」かつ「導入5分」で、デバッグの生産性が大きく変わります

この記事を書いた人
エーテリア編集部
エーテリア編集部

人気のPythonを初めて学ぶ方向けに、文法の基本から小さな自動化まで、実際に手を動かして理解できる記事を書いています。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!