こんにちは!ライターの遠藤です。今日はpythonでのデバッグの仕方について説明させていただきます!
printデバッグは面倒だし、消し忘れがあって嫌だ!
本記事ではそのような方へ向けて、
- デバッグとは何か
- pythonでのデバッグの方法
を説明致します。また、簡単な実用例もありますので、ニュアンスだけでも掴んでただけたら幸いです。ぜひ、最後までお付き合いください!
本記事を読む前に、Pythonがどんなプログラミング言語なのかをおさらいしておきたい人は次の記事を参考にしてください。
→ Pythonとは?特徴やできること、活用例をわかりやすく簡単に解説
なお、その他のPythonの記事についてはこちらにまとめています。
そもそもデバッグとは?
デバッグとは、端的に言うとプログラムの問題点(バグ)を見つける事を言います。
作成したプログラムを実行しようとしたのにエラーとなってしまったり、実行結果が期待していたものと違っていたりなど、プログラミングをしている以上必ずと言っていいほど問題は起こります。
そんな時に、どこがエラーとなっていたのか、どこで値が期待するものと違ってしまったのかなどを調べる作業がデバッグです。効率的なデバッグを行えるようになると、仕事が捗るようになります!
また、デバッグをする際はprint()を沢山入れてデバッグをしている方もいるかと思います。
簡単な問題点を見つける際はその方が効率的な場合もありますが、それが大きな規模となるとprint()をどこに入れていいのかわからなくなったり、デバッグが終わった後に不要なprint()を削除したりと手間になってしまいます。
それに対して今回説明させていただくデバッグ方法は、2行追加するだけでIDE(統合開発環境)を入れてなくても標準出力から行う事ができます。本記事のデバッグの方法を使えるようにして、楽にデバッグを進められるようになりましょう!
デバッグのやり方
pythonのデバッグのやり方は簡単です。pdbをインポートして、set_trace()を呼ぶだけです。なんとこれだけで、実行した時にその行からデバッグを行うことができます。
実際にデバッグが開始されるところまでを確認してみましょう。
#! /usr/bin/env python # coding: UTF-8 import pdb #まずpdbをインポート pdb.set_trace() #ここでset_trace() print("Hello World!")
実行結果:
> XXX/set_trace.py(8)<module>() -> print("Hello World!") (Pdb)
これはset_trace()を入れた事により、”Hello World!”が表示される手前のところで止まっている状態です。ここから(Pdb)の後にコマンドを入れることによって、デバッグを進めていくことができます。
基礎的なコマンド一覧
set_trace()でデバッグの開始方法がわかったところで、実際のコマンド入力の方法を説明します。
こちらもやることは簡単で、(Pdb)の後にコマンドの1文字を入力して決定するだけ<です。以下に基本的なコマンドの一覧をまとめました。
コマンド | できる事 |
---|---|
h(elp) | 利用できるコマンドが確認できます。 |
s(tep) | 現在の行を実行し、現在の関数の次の行または次の行で呼び出された関数の中で停止します。 |
n(ext) | 現在の関数の次の行に達するか、あるいは次の行の関数が返るまで実行します。 (sは次の関数の入り口、nは次の関数の出口というニュアンス) |
p(rint) | 引数として指定した変数の値を返します。 |
r(eturn) | 現在の関数が返るまで実行します。 |
c(ont(inue)) | 次のブレークポイントまで実行します。 |
j(ump) | 次に実行する行を指定します。ただし、for文の中などへ入れないなどの制限があります。 |
l(ist) | 現在のファイルのソースコードを表示します。 |
a(rgs) | 現在の関数の引数リストを表示します。 |
run, restart | デバッグ中のプログラムを(再)実行します。 |
q(uit) | デバッグを終了します。 |
これを参考にコマンドを入力していきましょう。
実用例
では、実際にデバッグを試して見ましょう。以下のプログラムで”d”の戻り値を期待してkey_from_value(20)と関数呼び出しをします。
#! /usr/bin/env python # coding: UTF-8 ls = {"a": 10, "b": 20, "c": 30, "d": 20, "e": 50} def key_from_value(i): for key, value in ls.items(): if value == i: return key ret = key_from_value(20) print(ret)
これを実行すると、
実行結果:
b
“b”が返ってきてしまいましたので、デバッグをしてどのように処理されているかを確認します。(本来ならリストを見たら一目で問題点がわかりますが、説明のためデバッグをします!)
先ほど説明した通りの2行をコードに追加します。
#! /usr/bin/env python # coding: UTF-8 import pdb #まずpdbをインポート ls = {"a": 10, "b": 20, "c": 30, "d": 20, "e": 50} def key_from_value(i): pdb.set_trace() #ここでset_trace()をセットします for key, value in ls.items(): if value == i: return key ret = key_from_value(20) print(ret)
これを実行してみましょう。
実行結果:
> XXX/sample.py(10)key_from_value() -> for key, value in ls.items(): (Pdb)
と表示され、入力ができるようになっています。
ここで、コマンド一覧にある”l”を入力します。
(Pdb) l 5 6 ls = {"a": 10, "b": 20, "c": 30, "d": 20, "e": 50} 7 8 def key_from_value(i): 9 pdb.set_trace() #ここでset_trace() 10 -> for key, value in ls.items(): 11 if value == i: 12 return key 13 14 ret = key_from_value(20) 15 print(ret) (Pdb)
現在の行と前後の行が表示されている事がわかります。
続いて、nを入力します。
(Pdb) n > XXX/code.py(11)key_from_value() -> if value == i:
次の行へ移りました。
ここで、現在のvalueの値を確認してみます。”p value”と入力します。
(Pdb) p value 10
リストの最初の値である”10″となっている事が確認できました。
引き続きnを入力します。
(Pdb) n > XXX/code.py(10)key_from_value() -> for key, value in ls.items():
一つ前の行に戻っています。これは、for文が終了して、次の値でループしているという事です。
先ほどと同様にコマンドを入力していきます。
(Pdb) n > XXX/code.py(11)key_from_value() -> if value == i: (Pdb) n > XXX/code.py(12)key_from_value() -> return key (Pdb)
ここでif文の中に入ってしまった事が確認できました。
この時のkeyとvalueの値を確認してみましょう。”p key, value”と入力します。
(Pdb) p key, value ('b', 20) (Pdb)
ここでbの中の値が20となっている為にif文に一致して、戻り値がbとなっている事がわかりました。このようにデバッグを行う事で、ひとつひとつの値や処理を確認しながら問題点を見つける事ができるのです。
まとめ
いかがでしたか?今回の記事では、
- デバッグとは
- pythonでのデバッグ方法
について、実際のコードを交えて説明致しました。pythonではIDEがなくても2行追加するだけでデバッグができるので、比較的気軽かと思います。この記事でデバッグの基礎を学んで、快適なデバッグライフを送ってください!