Pythonの基本的なエラー一覧とその原因の確認方法
Pythonの基本的なエラー・例外の一覧とその原因の確認方法・対処方法について説明する。
Pythonにおけるエラーと例外
Pythonにおいて、エラーは構文エラー(Syntax error)と例外(Exception)に区別される。
構文として誤っているものは構文エラー、構文として正しくても実行中に発生するエラーは例外と呼ばれる。
エラーには (少なくとも) 二つのはっきり異なる種類があります。それは 構文エラー (syntax error) と 例外 (exception) です。
…
実行中に検出されたエラーは 例外 (exception) と呼ばれ、常に致命的とは限りません。
8. エラーと例外 — Python 3.11.4 ドキュメント
本記事では想定内の例外を捕捉し対応する例外処理ではなく、想定外のエラー・例外の原因の確認方法および対処方法について説明する。例外処理については以下の記事を参照。
また、エラーや例外のようにプログラムが途中終了することはないがユーザーにメッセージを出力する警告(Warning)もある。
以降は「エラー」と「例外」を特に使い分けず、すべて「エラー」と呼ぶ。
エラーメッセージの内容
エラーが発生すると以下のようなエラーメッセージが出力される。エラーの発生箇所がファイル名と行番号とともに表示され、最終行にはエラーの内容と具体的な説明が示される。
l = 100
l.append(200)
# Traceback (most recent call last):
# File "/Users/mbp/Documents/my-project/python-snippets/errors.py", line 2, in <module>
# l.append(200)
# AttributeError: 'int' object has no attribute 'append'
AttributeError
やTypeError
などのような最終行に書かれている内容を確認することでエラーの原因が推測できる。コロン:
のあとの詳細説明はそれほど難しい英文ではないので英語が苦手でもしっかり読むべき。
以下、基本的なエラーの一覧を、エラー箇所およびエラーメッセージをコメントアウトしたコードと修正したコードとともに例示する。
すべての組み込み例外の一覧は公式ドキュメントを参照。
なお、エラーメッセージはPythonのバージョンによって異なる可能性がある。
構文に関するエラー
SyntaxError
Pythonの構文として正しくないというエラー。高機能なエディタやIDEを使っていれば実行前にチェックしてくれることが多い。
括弧()
やコロン:
が足りない場合などに発生。
# print('hello'
# SyntaxError: incomplete input
print('hello')
# hello
# for i in range(3)
# print(i)
# SyntaxError: expected ':'
for i in range(3):
print(i)
# 0
# 1
# 2
IndentationError
インデントが正しくないというエラー。上記SyntaxError
のサブクラス(子クラス)。
同じレベルであるべきインデントが一致していない場合などに発生。
n = 100
# if n == 100:
# print('n is 100')
# else:
# print('n is not 100')
# IndentationError: unindent does not match any outer indentation level
n = 100
if n == 100:
print('n is 100')
else:
print('n is not 100')
# n is 100
インポートに関するエラー
ImportError
import
でモジュールやオブジェクトをインポートするときに問題が発生したというエラー。
from <モジュール名> import <オブジェクト名(関数名など)>
でモジュールに含まれていないオブジェクトをインポートしようとしたときなどに発生。大文字小文字も区別されるので注意。
# from math import COS
# ImportError: cannot import name 'COS' from 'math' (/opt/homebrew/Cellar/[email protected]/3.11.4_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/lib-dynload/math.cpython-311-darwin.so)
from math import cos
確認項目
- モジュール名、オブジェクト名は正しいか
- 対象のモジュールに本当にそのオブジェクトが含まれているか
- 公式ドキュメントなどを確認
ModuleNotFoundError
指定したモジュールが見つからないというエラー。上記ImportError
のサブクラス(子クラス)。
# import mathematics
# ModuleNotFoundError: No module named 'mathematics'
import math
そもそも対象のモジュールがインストールされていないか、自作のモジュールの場合は検索パスの設定が間違っている可能性がある。
モジュール内のオブジェクトを直接インポートしようとした場合もエラーとなる。オブジェクトを直接インポートするにはfrom
を使う。
# import math.pi
# ModuleNotFoundError: No module named 'math.pi'; 'math' is not a package
from math import pi
確認項目
- モジュール名は正しいか
- 対象のモジュールが本当にインストールされているか
pip list
コマンドなどでインストールされているモジュールを確認- 関連記事: Python, pip list / freezeでインストール済みパッケージ一覧を確認
- モジュール検索パスは正しく設定されているか
型や値、名前に関するエラー
AttributeError
属性(Attribute)参照に関するエラー。
<オブジェクト>.<識別子>
のように属性やメソッドなどを呼び出す際に、オブジェクトや識別子(属性やメソッド)の名前、オブジェクトの型を間違えている場合に発生する。大文字小文字も区別される。
識別子の名前を間違えている例。
import math
# print(math.PI)
# AttributeError: module 'math' has no attribute 'PI'
print(math.pi)
# 3.141592653589793
オブジェクトの型が想定と異なっている例。
l = 100
# l.append(200)
# AttributeError: 'int' object has no attribute 'append'
l = [100]
l.append(200)
print(l)
# [100, 200]
確認項目
- オブジェクト名、識別子名は正しいか
- オブジェクトの型は想定通りか
TypeError
不適切な型(Type)に対して演算や組み込み関数による処理が行われたというエラー。
異なる型のオブジェクトを+
演算子で加算しようとした例。
n = '100'
# print(n + 200)
# TypeError: can only concatenate str (not "int") to str
n = 100
print(100 + 200)
# 300
文字列や数値を浮動小数点数(float
)に変換する組み込み関数float()
にそのほかの型のオブジェクトを渡した例。
# print(float(['1.23E-3']))
# TypeError: float() argument must be a string or a number, not 'list'
print(float('1.23E-3'))
# 0.00123
確認項目
- 演算するオブジェクトの型は正しいか
- 関数に渡すオブジェクトの型は正しいか
ValueError
演算子や関数の処理において、型は合っているが値が適切でないというエラー。
例えばfloat()
は文字列(str
)を浮動小数点数(float
)に変換するが、元の文字列が変換可能な値でないとエラーになる。
# print(float('float number'))
# ValueError: could not convert string to float: 'float number'
print(float('1.23E-3'))
# 0.00123
確認項目
- 演算する値は適切か
- 関数に渡す値は適切か
ZeroDivisionError
0で割り算が行われたというエラー。
除算/
だけでなく、整数除算//
、剰余演算%
でも発生する。
n = 100
zero = 0
# print(n / zero)
# ZeroDivisionError: division by zero
# print(n // zero)
# ZeroDivisionError: integer division or modulo by zero
# print(n % zero)
# ZeroDivisionError: integer modulo by zero
変数で割る場合、除算の前段階で期せずしてゼロになってしまっている可能性がある。
確認項目
- 除数(割る数)がゼロになっていないか
NameError
名前が見つからないというエラー。
変数名のスペル間違いなどで発生する。 大文字小文字も区別されるので注意。
my_number = 100
# print(myNumber)
# NameError: name 'myNumber' is not defined
print(my_number)
# 100
確認項目
- 対象の変数は定義されているか
- スペルは正しいか
インデックスやキーに関するエラー
IndexError
リストやタプルなどのシーケンスオブジェクトに格納された値を[インデックス]
で取得する際に、範囲外の位置(要素数を超えたインデックス値)が指定されたというエラー。
リストやタプルの要素数はlen()
で確認できる。
- 関連記事: Pythonでリストのサイズ(要素数)を取得
l = [0, 1, 2]
# print(l[100])
# IndexError: list index out of range
print(len(l))
# 3
print(l[1])
# 1
確認項目
- シーケンスオブジェクトの要素数は想定通りか
- インデックスとして指定した値は正しいか
KeyError
辞書(dict
)の値をキーを指定して取得する際に、存在しないキーが指定されたというエラー。
d = {'a': 1, 'b': 2, 'c': 3}
# print(d['x'])
# KeyError: 'x'
print(d['a'])
# 1
辞書のキーの一覧はkeys()
メソッドで確認可能。
print(d)
# {'a': 1, 'b': 2, 'c': 3}
print(d.keys())
# dict_keys(['a', 'b', 'c'])
get()
メソッドを使うと、存在しないキーに対してもエラーにならずデフォルト値を取得できる。
print(d.get('x'))
# None
確認項目
- 辞書に含まれるキーは正しいか
- 指定したキーは正しいか
ファイルやディレクトリに関するエラー
FileNotFoundError
open()
でファイルを読み込む際などに指定したファイルが見つからないというエラー。
# with open('not_exist_file.txt') as f:
# print(f.read())
# FileNotFoundError: [Errno 2] No such file or directory: 'not_exist_file.txt'
相対パスで指定した場合は、Pythonのカレントディレクトリが想定と異なっている可能性もある。
確認項目
- 指定したファイルは本当に存在しているか
- 指定したパスは正しいか
- 相対パスで指定した場合、カレントディレクトリは正しいか
FileExistsError
すでに存在しているファイルやディレクトリを作成しようとした場合のエラー。
import os
# os.mkdir('data')
# FileExistsError: [Errno 17] File exists: 'data'
バージョン3.2以降のos.makedirs()
では引数exist_ok
が追加されており、exist_ok=True
とするとすでに存在しているディレクトリを作成しようとしてもエラーにならない。
確認項目
- 指定したファイル・ディレクトリがすでに存在していないか