タイトル: エラー一覧
SEOタイトル: Python よくあるエラー集と対処完全ガイド
| この記事の要点 |
|
Python エラーの読み方 (traceback)
エラー時に表示される traceback は下から上に読むのが鉄則。最下行が実際の例外と原因です:
Traceback (most recent call last): # 呼び出し履歴の見出し
File "main.py", line 10, in # ① 入口
result = process_data(data)
File "main.py", line 5, in process_data # ② 中間
return user['name'].upper()
KeyError: 'name' # ③ ★ 実際のエラー
SyntaxError: invalid syntax
Python のパース段階で構文エラー。コードは1 行も実行されません。
# ❌ コロン抜け
if x > 0
print(x)
# SyntaxError: invalid syntax
# ❌ 括弧の閉じ忘れ
print("hello"
# → SyntaxError: '(' was never closed
# ❌ Python 2 文法
print "hello"
# → SyntaxError: Missing parentheses in call to 'print'
# ✅ 修正
if x > 0:
print(x)
print("hello")
IndentationError
# ❌ インデント不一致
def foo():
if True:
print("a") # スペース 2 個
print("b") # スペース 8 個 → IndentationError: unexpected indent
# ❌ タブとスペース混在 → TabError: inconsistent use of tabs and spaces
# ✅ PEP 8 推奨: スペース 4 個で統一
# エディタで「タブをスペースに変換」を有効化
NameError: name 'x' is not defined
# ❌ タイプミス
counter = 0
counter += 1
print(conter) # → NameError: name 'conter' is not defined
# ❌ import 漏れ
print(math.pi) # → NameError: name 'math' is not defined
# 対処: import math を追加
# ❌ スコープ違反
def increment():
counter += 1 # → UnboundLocalError (NameError の親戚)
# 対処: global counter or nonlocal を宣言、or 引数で渡す
# ❌ 関数定義より先に呼び出し
foo()
def foo(): pass
# → NameError (実行時の順序問題)
TypeError
# ❌ 異なる型の演算
result = "10" + 5
# → TypeError: can only concatenate str (not "int") to str
# 対処: "10" + str(5) or int("10") + 5
# ❌ None に対する演算
x = None
y = x + 1
# → TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
# ❌ 引数数間違い
def greet(name): print(name)
greet("a", "b")
# → TypeError: greet() takes 1 positional argument but 2 were given
# ❌ self 忘れ (Python の典型ミス)
class Foo:
def bar(): # ← self が無い
pass
Foo().bar()
# → TypeError: bar() takes 0 positional arguments but 1 was given
ValueError
# ❌ 変換不能
int("abc")
# → ValueError: invalid literal for int() with base 10: 'abc'
# ❌ アンパック数違い
a, b = [1, 2, 3]
# → ValueError: too many values to unpack (expected 2)
# ❌ math.sqrt(負数)
import math
math.sqrt(-1)
# → ValueError: math domain error
# 対処: cmath.sqrt(-1) で複素数対応
KeyError / IndexError
# ❌ 辞書のキー無し
data = {'name': '田中'}
print(data['age'])
# → KeyError: 'age'
# ✅ 対処
print(data.get('age')) # None
print(data.get('age', 0)) # デフォルト値
if 'age' in data:
print(data['age'])
# ❌ リスト範囲外
nums = [1, 2, 3]
print(nums[5])
# → IndexError: list index out of range
# ✅ 対処
if len(nums) > 5:
print(nums[5])
# または try/except
try:
print(nums[5])
except IndexError:
pass
AttributeError: 'NoneType' object has no attribute 'X'
Python で最も頻発するエラー。「None に対してメソッド呼び出し」がほぼ全ての原因です:
# ❌ None からメソッド呼び出し
user = User.objects.filter(id=999).first() # → None
print(user.name)
# → AttributeError: 'NoneType' object has no attribute 'name'
# ✅ 対処1: None チェック
if user is not None:
print(user.name)
# ✅ 対処2: get_or_404 等の例外化
user = get_object_or_404(User, id=999)
# ✅ 対処3: walrus 演算子 (Python 3.8+)
if (user := User.objects.filter(id=999).first()) is not None:
print(user.name)
# ❌ 戻り値 None を期待外に使う
result = my_list.sort() # sort() は None を返す
print(result.reverse())
# → AttributeError: 'NoneType' object has no attribute 'reverse'
# 対処: my_list.sort() の後に my_list を使う、または sorted() を使う
ImportError / ModuleNotFoundError
# ❌ パッケージ未インストール
import requests
# → ModuleNotFoundError: No module named 'requests'
# 対処: pip install requests
# ❌ venv の不一致(VS Code のインタプリタ違い、複数 Python)
which python
which pip
python -m pip install requests # ★ -m pip で確実
# ❌ 相対 import
# project/
# __init__.py
# pkg/
# __init__.py
# a.py
# b.py
# a.py 内
from b import foo
# → ModuleNotFoundError: No module named 'b'
# 対処: from .b import foo (パッケージ実行時) または PYTHONPATH 調整
# ❌ 循環 import
# a.py: from b import x
# b.py: from a import y
# → ImportError: cannot import name 'x' from partially initialized module 'b'
# 対処: 共通モジュールに切り出す、関数内 import で遅延
RecursionError
# ❌ 終了条件忘れ
def factorial(n):
return n * factorial(n - 1)
factorial(10)
# → RecursionError: maximum recursion depth exceeded
# ✅ 終了条件を入れる
def factorial(n):
if n <= 1: return 1
return n * factorial(n - 1)
# 深い再帰が必要なら制限を引き上げ(注意)
import sys
sys.setrecursionlimit(10000)
UnicodeDecodeError / UnicodeEncodeError
# ❌ Shift-JIS ファイルを UTF-8 で読む
with open('sjis.csv') as f:
print(f.read())
# → UnicodeDecodeError: 'utf-8' codec can't decode byte 0x83...
# ✅ encoding 指定
with open('sjis.csv', encoding='cp932') as f:
print(f.read())
# ✅ どうしてもダメな箇所をスキップ
with open('sjis.csv', encoding='utf-8', errors='ignore') as f:
print(f.read())
# errors=: strict / ignore / replace / backslashreplace / xmlcharrefreplace
StopIteration
# next() でイテレータの終端に達した
it = iter([1, 2, 3])
next(it) # 1
next(it) # 2
next(it) # 3
next(it) # → StopIteration
# ✅ デフォルト値
next(it, None) # None
# generator の return も StopIteration になる
def gen():
yield 1
return "end"
g = gen()
next(g) # 1
try:
next(g)
except StopIteration as e:
print(e.value) # "end"
その他よく見るエラー
| エラー | 主な原因 | 対処 |
|---|---|---|
ZeroDivisionError | 0 で除算 | 分母を事前チェック |
FileNotFoundError | ファイル存在しない / カレントディレクトリ違い | 絶対パス / pathlib.Path / os.path.exists |
PermissionError | 権限不足 | chmod / 実行ユーザー確認 |
JSONDecodeError | JSON 文法エラー | レスポンス本文を print して確認 |
OSError: [Errno 98] Address already in use | ポート占有 | 別ポート / プロセス kill |
MemoryError | メモリ不足 | generator / chunk 化 |
EOFError | input() でファイル終端 | try/except 包む |
AssertionError | assert 失敗 | 条件確認、本番では python -O で無効化される |
エラーハンドリングのベストプラクティス
# ❌ 何でもキャッチ(バグを隠す)
try:
do_something()
except:
pass
# ❌ 広すぎる Exception
try:
do_something()
except Exception:
pass
# ✅ 想定されるものだけキャッチ
try:
response = requests.get(url, timeout=5)
response.raise_for_status()
data = response.json()
except requests.Timeout:
logger.warning('timeout')
return None
except requests.HTTPError as e:
logger.error(f'HTTP {e.response.status_code}')
return None
except ValueError as e: # JSON decode
logger.error(f'invalid JSON: {e}')
return None
# ✅ ログには traceback を含める
import logging
try:
risky()
except Exception:
logging.exception('処理失敗') # traceback 含む
FAQ
Q: pip install したのに ModuleNotFoundError
A: 別の Python に入っている可能性。python -m pip install ... で「いま動かしている Python」に確実にインストール。VS Code はインタプリタの選択をチェック。
Q: print デバッグ以外で例外調査するには?
A: pdb.set_trace()(Python 3.7+ は breakpoint())でステップ実行。IDE のデバッガ(VS Code / PyCharm)も同等。
Q: 自分でエラーを投げたい
A: raise ValueError("メッセージ")。組み込みクラスを継承した独自例外クラスを作ると整理しやすい: class UserNotFoundError(LookupError): ...。