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
コマンドでその場の変数を調べたり、s
やn
で1行ずつ実行を追えます。
不要になったら1行削除するだけなので、ログの掃除も最小限です。
以下は対比のイメージです。
# 悪い例: 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
# 良い例: 確認したい行で止めるだけ
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()
で見抜く例です。
# ファイル名: 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
が起動します。
$ python shop.py
> .../shop.py(13)checkout()
-> return apply_discount(total, rate)
(Pdb)
変数や状態を確認
止まった時点のローカル変数や式の評価は、p
コマンドで確認できます。
現在位置の周辺コードはl
で一覧できます。
(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
で終了できます。
(Pdb) c
-20800
本番実行で停止するとサービス影響が出るため、breakpointは開発中に限定するか、後述のPYTHONBREAKPOINT
で無効化しましょう。
pdbの基本コマンド(初心者向け最小セット)
<p>最初は次の6つだけ覚えれば十分です。
すべて小文字1文字で使え、直感的に動かせます。
</p>
次の行へ進む(n)
現在の関数の次の行まで実行します。
関数呼び出しは「中に入らず」通過します。
(Pdb) n
> .../shop.py(11)checkout()
-> return apply_discount(total, rate)
関数に入る(s)
呼び出し先の関数に入って、その中の最初の行で停止します。
細かく内部を追いたい時に使います。
(Pdb) s
> .../shop.py(6)apply_discount()
-> return total - total * rate
続けて実行(c)
次のブレークポイントまで、またはプログラム終了まで一気に実行します。
停止したい箇所にbreakpoint()
が複数ある場合にも便利です。
(Pdb) c
-20800
変数を見る(p 変数名)
変数名や式を評価して表示します。
pp
で整形表示も可能です。
(Pdb) p rate
10
(Pdb) p total * rate
26000
(Pdb) pp {"total": total, "rate": rate}
{'total': 2600, 'rate': 10}
現在位置を一覧表示(l)
現在行の周辺コードを表示します。
もう一度l
を打つと次の範囲が表示されます。
(Pdb) l
8 def checkout(prices, rate):
9 total = subtotal(prices)
10 breakpoint()
11 return apply_discount(total, rate)
中断して終了(q)
デバッガを即終了し、プログラムも中断します。
実行途中で抜けたい場合に使います。
(Pdb) q
以下に最小セットの早見表を載せます。
コマンド | 動作の概要 | 補足 |
---|---|---|
n | 次の行へ進む | 呼び出し先には入らない |
s | 関数に入る | 呼び出し先の最初の行で停止 |
c | 続けて実行 | 次のbreakpointか終了まで進む |
p expr | 変数や式を表示 | pp で整形表示 |
l | ソース表示 | 再実行で続きが見られる |
q | 中断して終了 | 即座に抜ける |
環境変数PYTHONBREAKPOINTの活用
PYTHONBREAKPOINTはbreakpoint()の挙動を外部から切り替えるためのスイッチです。
インストールなしの標準デバッガ利用から、サードパーティ製への置き換え、一時無効化まで柔軟に制御できます。
別デバッガに切り替え(ipdbなど)
よりリッチなデバッガipdb
に切り替える例です。
ipdb自体は別途インストールが必要ですが、コード側はbreakpoint()
のままでOKです。
# インストール
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()は何もしません。
# 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のシェル初期化ファイルやシステム環境変数に登録します。
# macOS/Linux: 一時的にこの実行だけ(前置き)
PYTHONBREAKPOINT=ipdb.set_trace python shop.py
# macOS/Linux: セッション中ずっと有効
export PYTHONBREAKPOINT=ipdb.set_trace
python shop.py
# Windows PowerShell: セッション内で有効
$env:PYTHONBREAKPOINT = "ipdb.set_trace"
python .\shop.py
# 解除
Remove-Item Env:PYTHONBREAKPOINT
:: 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
で変数を確認し、n
やs
で追い、c
で再開するだけで、print()デバッグでは見逃しがちな「その瞬間の状態」を確実に掴めます。
さらにPYTHONBREAKPOINT
により、開発では有効、本番では無効といった運用切り替えやipdb
への置き換えも簡単です。
まずは小さなスクリプトでbreakpoint()
を1行差し込み、上で紹介した6コマンド(n
, s
, c
, p
, l
, q
)を試してみてください。
「VSCode不要」かつ「導入5分」で、デバッグの生産性が大きく変わります。