はじめに
この記事では、Pythonで開発する際によく遭遇するエラーの原因と対処法、そしてエラーとうまく付き合うためのベストプラクティスをまとめました。
エラーメッセージを恐れず、辞書のようにこの記事を活用して、スムーズな開発ライフを送りましょう。
エラーメッセージ(Traceback)の読み方
エラーが発生したとき、Pythonは「トレースバック(Traceback)」と呼ばれる情報を出力します。
初心者のうちは情報量に圧倒されるかもしれませんが、見るべきポイントは一番最後です。
Traceback (most recent call last):
File "example.py", line 10, in <module>
main()
File "example.py", line 5, in main
print(1 / 0)
ZeroDivisionError: division by zero
-
何が起きたか(例外クラスとメッセージ): 一番最後の行(
ZeroDivisionError: division by zero)を見ます。「ゼロ除算エラー」だと分かります。 -
どこで起きたか(ファイル名と行番号): その直前の行(
File "example.py", line 5)を見ます。example.pyの5行目で起きたことが分かります。
ここさえ押さえれば、解決への第一歩は踏み出せています。
よくある構文エラー (Syntax Errors)
プログラムを実行する前に、Pythonが「文法がおかしい」と判断したときに発生します。
SyntaxError: invalid syntax
最も一般的な文法エラーです。
-
原因:
-
if、for、defなどの行末のコロン(:)忘れ - 括弧
()、[]、{}の閉じ忘れ - 文字列のクォート
'、"の閉じ忘れ
-
-
Python 3.10以降の改善:
近年のPythonでは、どこが間違っているかより具体的に教えてくれるようになりました。
# ❌ 間違い例
if True
print("Hello")
# SyntaxError: expected ':'
IndentationError: unexpected indent
Pythonはインデント(字下げ)でブロックを判断するため、スペースの数が重要です。
-
原因:
- インデントが必要ない場所でインデントしている
- インデントのスペース数が揃っていない(推奨はスペース4つ)
- タブとスペースが混在している
# ❌ 間違い例
def my_func():
print("Hello") # インデントが必要
# IndentationError: expected an indented block
よくある実行時エラー (Runtime Errors)
文法は正しくても、プログラムの実行中に何らかの問題が発生した場合のエラーです。
NameError: name '...' is not defined
-
原因:
- 変数名や関数名のスペルミス(Typo)
- 定義する前に変数を使おうとしている
- 変数のスコープ(有効範囲)外からアクセスしている
message = "Hello"
print(mesage) # 's'が抜けている
# NameError: name 'mesage' is not defined
TypeError: ... object is not ...
データ型の使い方が間違っている場合に発生します。
-
原因:
- 整数と文字列を足そうとした(例:
10 + "20") -
len()関数を数値に使った -
Noneに対してメソッドを呼び出した
- 整数と文字列を足そうとした(例:
price = 100
print("価格は" + price + "円")
# TypeError: can only concatenate str (not "int") to str
対処法: str(price) のように型変換を行うか、f-string(f"価格は{price}円")を使用しましょう。
ValueError: invalid literal for ...
型は合っているけれど、中身の値が適切でない場合に発生します。
-
原因:
- 数字ではない文字列を
int()で変換しようとした
- 数字ではない文字列を
number = int("abc")
# ValueError: invalid literal for int() with base 10: 'abc'
IndexError / KeyError
データ構造の中に存在しない要素にアクセスしようとしたときに発生します。
-
IndexError: リスト(配列)の範囲外のインデックスを指定した
items = ["a", "b"] print(items[2]) # 要素は0と1のみ # IndexError: list index out of range -
KeyError: 辞書に存在しないキーを指定した
user = {"name": "Taro"} print(user["age"]) # KeyError: 'age'
対処法(辞書): .get() メソッドを使うと、キーがない場合にエラーにならず None を返してくれるので安全です。
print(user.get("age")) # None が出力される
AttributeError: '...' object has no attribute '...'
そのオブジェクトが持っていない属性やメソッドを使おうとしたときに発生します。
よくあるのが、変数が想定外に None になっていて発生するパターンです。
data = None
data.append(1)
# AttributeError: 'NoneType' object has no attribute 'append'
ModuleNotFoundError: No module named '...'
import しようとしたモジュールが見つからない場合に発生します。
-
原因:
- ライブラリがインストールされていない(
pip install忘れ) - 仮想環境(venv)が有効になっていない
- ファイル名のスペルミス
- ライブラリがインストールされていない(
エラーハンドリングのベストプラクティス
エラーは発生するものとして、適切に対処(ハンドリング)するコードを書くことが重要です。
1. try-except の正しい使い方
例外処理を使うことで、エラーが発生してもプログラムを強制終了させずに済みます。
ただし、何でもかんでもキャッチするのはNGです。
Web開発の文脈でコードを書いているのであればtry-exceptを使ってエラーハンドリングしましょう
❌ 悪い例: 全てのエラーを握りつぶしてしまう
try:
some_risky_operation()
except:
pass # エラーが起きても何もしない(原因が分からなくなる!)
⭕ 良い例: 特定のエラーをキャッチし、適切にログを出す
try:
result = 10 / 0
except ZeroDivisionError:
print("ゼロで割ることはできません")
except Exception as e:
# 予期せぬエラーは内容を表示する
print(f"予期せぬエラーが発生しました: {e}")
2. print デバッグから卒業しよう
開発中、変数の値を確認するために print() を多用しがちですが、本番レベルのコードでは logging モジュールを使いましょう。
ログレベル(DEBUG, INFO, ERRORなど)を切り替えることで、出力の制御が容易になります。
import logging
logging.basicConfig(level=logging.ERROR)
logging.error("これはエラーログです")
3. 静的解析ツール(Linter)の活用
実行する前にコードの問題を見つけてくれるツールを活用しましょう。
エディタ(VS Codeなど)に入れておくと、リアルタイムで警告を出してくれます。
- Flake8: 構文エラーやコーディングスタイル(PEP 8)違反をチェック
- Pylint: より詳細なコード分析
- Black: コードを自動で綺麗に整形(フォーマット)してくれる
まとめ
エラーは怖くありません。むしろ、バグの原因を即座に教えてくれる頼もしい味方です。
頻出するエラーパターンを知っておけば、「またこれか」と落ち着いて対処できるようになります。
- Tracebackの最後を見る
- エラーの種類(SyntaxError, NameError...)を確認する
- 該当の行番号前後のコードを見直す