note.nkmk.me

Pythonの基本的なエラー一覧とその原因の確認方法

Date: 2018-08-09 / tags: Python
このエントリーをはてなブックマークに追加

Pythonの基本的なエラー・例外の一覧とその原因の確認方法について説明する。原因が明らかになればそれを修正するのは簡単。

以下の内容について説明する。

  • エラーと例外
  • エラーメッセージの読み方
  • 構文に関するエラー
  • インポートに関するエラー
  • 型や値、名前に関するエラー
  • インデックスやキーに関するエラー
  • ファイルやディレクトリに関するエラー
スポンサーリンク

エラーと例外

Pythonにおいて、エラーは構文エラー(syntax error)と例外(exception)に区別される。

構文として誤っているものは構文エラー、構文として正しくても実行中に発生するエラーは例外と呼ばれる。

エラーには (少なくとも) 二つのはっきり異なる種類があります。それは 構文エラー (syntax error) と 例外 (exception) です。

実行中に検出されたエラーは 例外 (exception) と呼ばれ、常に致命的とは限りません。
8. エラーと例外 — Python 3.6.5 ドキュメント

ここでは想定内の例外を捕捉し対応する例外処理ではなく、想定外のエラー・例外の原因の確認方法について説明する。

なお、以降は「エラー」と「例外」を特に使い分けず、すべて「エラー」と呼ぶ。

エラーメッセージの内容

エラーが発生すると以下のようなエラーメッセージが出力される。エラーが発生したファイル名、および、エラー箇所が行番号とともに表示され、最終行にはエラーの内容と具体的な説明が示される。

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'

AttributeErrorTypeErrorなどのような最終行の内容を確認することでエラーの原因が推測できる。コロン:のあとの詳細説明はそれほど難しい英文ではないので英語が苦手でもしっかり読むべき。

以下、基本的なエラーの一覧をエラー箇所およびエラーメッセージをコメントアウトしたコードと修正したコードとともに例示する。

そのほかすべての組み込み例外は公式ドキュメントを参照。

構文に関するエラー

Pythonの構文として正しくない場合のエラー。高機能なエディタやIDEを使っていれば実行前にチェックしてくれることが多い。

SyntaxError

括弧()やコロン:が足りない場合などのエラー。

# print('hello'

# SyntaxError: unexpected EOF while parsing

print('hello')
# hello
source: errors.py
# for i in range(3)
#     print(i)

# SyntaxError: invalid syntax

for i in range(3):
    print(i)
# 0
# 1
# 2
source: errors.py

IndentationError

インデントが正しくない場合のエラー。

同じ階層であるべきインデントが一致していなかったりする場合など。

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
source: errors.py

インポートに関するエラー

ModuleNotFoundError

モジュールが見つからないというエラー。

# import mathematics

# ModuleNotFoundError: No module named 'mathematics'

import math

print(math.pi)
# 3.141592653589793
source: errors.py

そもそも対象のモジュールがインストールされていないか、自作のモジュールの場合は検索パスの設定が間違っている可能性がある。

モジュール内のオブジェクトを直接インポートしようとした場合もエラーとなる。オブジェクトを直接インポートする場合はfromを使う。

# import math.pi

# ModuleNotFoundError: No module named 'math.pi'; 'math' is not a package

from math import pi

print(pi)
# 3.141592653589793
source: errors.py

インポートに関する詳細は以下の記事を参照。

ModuleNotFoundErrorはバージョン3.6で追加された。それより前のバージョンでは次に説明するImportErrorが送出される。

確認項目

ImportError

from <モジュール名> import <オブジェクト名(関数名など)>でモジュールに含まれていないオブジェクトをインポートしようとしたときなどのエラー。

大文字小文字も区別されるので注意。

# from math import COS

# ImportError: cannot import name 'COS' from 'math' (/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/math.cpython-37m-darwin.so)

from math import cos

print(cos(0))
# 1.0
source: errors.py

確認項目

  • モジュール名、オブジェクト名は正しいか
  • 対象のモジュールに本当にそのオブジェクトが含まれているか
    • 公式ドキュメントなどを確認

型や値、名前に関するエラー

AttributeError

属性(Attribute)参照に関するエラー。

<オブジェクト>.<識別子>のようにメソッドなどを呼び出す際に、オブジェクトや識別子(属性やメソッド)の名前、オブジェクトの型を間違えている場合に発生する。

識別子の名前を間違えている例。

import math

# print(math.PI)

# AttributeError: module 'math' has no attribute 'PI'

print(math.pi)
# 3.141592653589793
source: errors.py

オブジェクトの型が想定と異なっている例。

l = 100

# l.append(200)

# AttributeError: 'int' object has no attribute 'append'

l = [100]

l.append(200)
print(l)
# [100, 200]
source: errors.py

確認項目

TypeError

不適切な型に対して演算や組み込み関数による処理が行われた場合のエラー。

異なる型のオブジェクトを+演算子で加算しようとした場合や、文字列や数値を浮動小数点型(float)に変換する組み込み関数float()にそのほかの型のオブジェクトを渡した場合など。

n = '100'

# print(n + 200)

# TypeError: can only concatenate str (not "int") to str

n = 100

print(100 + 200)
# 300
source: errors.py
# print(float(['1.23E-3']))

# TypeError: float() argument must be a string or a number, not 'list'

print(float('1.23E-3'))
# 0.00123
source: errors.py

確認項目

  • 演算するオブジェクトの型は正しいか
  • 関数に渡すオブジェクトの型は正しいか

ValueError

型は合っているが値が適切でない場合のエラー。

例えば組み込み関数float()は文字列(str)を浮動小数点(float)に変換するが、元の文字列が変換可能な値でないとエラーになる。

# print(float('float number'))

# ValueError: could not convert string to float: 'float number'

print(float('1.23E-3'))
# 0.00123
source: errors.py

確認項目

  • 関数に渡す値は適切か

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 division or modulo by zero
source: errors.py

変数で割る場合、除算の前段階で期せずしてゼロになってしまっている可能性がある。

確認項目

  • 除数(割る数)がゼロになっていないか

NameError

名前が見つからなかった場合のエラー。

変数名のスペル間違いなど。 大文字小文字も区別されるので注意。

my_number = 100

# print(myNumber)

# NameError: name 'myNumber' is not defined

print(my_number)
# 100
source: errors.py

確認項目

  • 対象の変数は定義されているか
  • スペルは正しいか

インデックスやキーに関するエラー

IndexError

リストやタプルなどのシーケンスオブジェクトに格納された値を[インデックス]で取得する際に、範囲外の位置(要素数を超えたインデックス値)を指定してしまった場合のエラー。

リストやタプルの要素数はlen()で確認可能。

l = [0, 1, 2]

# print(l[100])

# IndexError: list index out of range

print(len(l))
# 3

print(l[1])
# 1
source: errors.py

確認項目

  • シーケンスオブジェクトの要素数は正しいか
  • インデックスとして指定した値は正しいか

KeyError

辞書(dict型)の値をキーを指定して取得する際に、存在しないキーを指定してしまった場合のエラー。

d = {'a': 1, 'b': 2, 'c': 3}

# print(d['x'])

# KeyError: 'x'

print(d['a'])
# 1
source: errors.py

キーの一覧はkeys()メソッドで確認可能。

print(d)
# {'a': 1, 'b': 2, 'c': 3}

print(list(d.keys()))
# ['a', 'b', 'c']
source: errors.py

get()メソッドを使うと存在しないキーに対してもエラーにならずデフォルト値を取得できる。

print(d.get('x'))
# None
source: errors.py

確認項目

  • 辞書に含まれるキーは正しいか
  • 指定したキーは正しいか

ファイルやディレクトリに関するエラー

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'
source: errors.py

相対パスで指定した場合は、Pythonのカレントディレクトリが想定と異なっている可能性もある。

確認項目

  • 指定したファイルは本当に存在しているか
  • 指定したパスは正しいか
  • 相対パスで指定した場合、カレントディレクトリは正しいか

FileExistsError

すでに存在しているファイルやディレクトリを作成しようとした場合のエラー。

import os

# os.mkdir('data')

# FileExistsError: [Errno 17] File exists: 'data'
source: errors.py

バージョン3.2以降のos.makedirs()では引数exist_okが追加されており、exist_ok=Trueとするとすでに存在しているディレクトリを作成しようとしてもエラーにならない。

確認項目

  • 指定したファイル・ディレクトリがすでに存在していないか
スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事