Select Language

AI Technology Community

6.6、Pythonによく見られる異常タイプのまとめ

この節では、一般的なシステム定義の例外クラスを紹介します。これらのオブジェクトが投げられたのを見たら、おおよそ何が起こったのかを理解できるようになります。

たとえば、コードの実行ログの中で次のような例外を見た場合:

トレースバック (最近の呼び出し履歴):
  ファイル "<stdin>", 1行目, <モジュール> 内
TypeError: / 演算子に対するサポートされていないオペランドの型: 'str' と 'float'

この場合、TypeError 例外の種類から、おおよそ何らかの変数の型が間違っていることがわかります。関連するオブジェクトの型を確認することで、この問題の原因を特定できます。

以下は、いくつかの一般的なシステム例外の種類です:
1) baseException:すべての例外の基底クラス。

2) AttributeError:存在しない属性にアクセスした場合。

>>> a = 12
>>> a.time                                                                     # 整数にはtime属性がありません
トレースバック (最近の呼び出し履歴):
  ファイル "<stdin>", 1行目, <モジュール> 内
AttributeError: 'int' オブジェクトには 'time' 属性がありません


3) AssertionError:assert アサーション文が失敗した場合。

>>> a = 2
>>> assert a < 1
トレースバック (最近の呼び出し履歴):
  ファイル "<stdin>", 1行目, <モジュール> 内
AssertionError


4) EOFError:ファイルの末尾に到達した場合。ファイルを開いて読み取り操作を繰り返し、ファイルの末尾に達するとこの例外が投げられます。Windows では、Ctrl+D を押すとこの例外が発生します。

>>> input("名前を入力してください >>>")
        # Ctrl+D を押す
名前を入力してください >>>トレースバック (最近の呼び出し履歴):
  ファイル "<stdin>", 1行目, <モジュール> 内
EOFError


5) IndentationError:インデントエラー。Python ではコードブロックのインデントを揃える必要があり、インデントが不揃いの場合はこの例外が投げられます。

>>>    m=12               # m の前に余分な空白があり、インデントが不正になっています
  ファイル "<stdin>", 1行目
    m=12
    ^
IndentationError: 予期しないインデント


6) IndexError:不正なインデックス。要素の範囲を超えた位置を指定した場合など。

>>> list_obj1 = []                             # 空のリスト
>>> list_obj1[10]                              # 11番目の要素は存在しません
トレースバック (最近の呼び出し履歴):
  ファイル "<stdin>", 1行目, <モジュール> 内
IndexError: リストのインデックスが範囲外です


7) KeyError:存在しないキーにアクセスした場合。

>>> dict_obj1 = {}                             # 空の辞書を作成
>>> dict_obj1['a']                             # 'a' というキーは存在しません
トレースバック (最近の呼び出し履歴):
  ファイル "<stdin>", 1行目, <モジュール> 内
KeyError: 'a'


8) KeyboardInterrupt:キーボードで Ctrl+C を押すとこの例外が発生します。

>>>             # Ctrl+C を押す
KeyboardInterrupt


9) ModuleNotFoundError

>>> import nonexistmodule          # 存在しないモジュールをインポート
トレースバック (最近の呼び出し履歴):
  ファイル "<stdin>", 1行目, <モジュール> 内
ModuleNotFoundError: 'nonexistmodule' という名前のモジュールが見つかりません


10) NameError:定義されていないオブジェクトを使用した場合。

>>> m                          # 存在しない変数
トレースバック (最近の呼び出し履歴):
  ファイル "<stdin>", 1行目, <モジュール> 内
NameError: 'm' という名前は定義されていません


11) RecursionError:再帰の深さが設定された最大値を超えた場合。

>>> def demo(a):                # 再帰関数、再帰の深さは a の値に等しい
...     if a > 0:
...         return demo(a-1)
...     else:
...         return a
...
>>> demo(10000)
トレースバック (最近の呼び出し履歴):
  ファイル "<stdin>", 1行目, <モジュール> 内
  ファイル "<stdin>", 3行目, demo 関数内
  ファイル "<stdin>", 3行目, demo 関数内
  ファイル "<stdin>", 3行目, demo 関数内
  [前の行がさらに 995 回繰り返されました]
  ファイル "<stdin>", 2行目, demo 関数内
RecursionError: 比較で再帰の最大深さを超えました


12) SyntaxError:構文エラー。

>>> a = 12
>>> a--
  ファイル "<stdin>", 1行目
    a--
      ^
SyntaxError: 無効な構文


13) TypeError:データ型エラー。たとえば、除算演算子は両方のオペランドが数値である必要があり、文字列は使用できません。そうでない場合は TypeError が投げられます。

>>> "abc" / 12                                 # 被除数の型が間違っています
トレースバック (最近の呼び出し履歴):
  ファイル "<stdin>", 1行目, <モジュール> 内
TypeError: / 演算子に対するサポートされていないオペランドの型: 'str' と 'int'
>>> 12 / "abc"                                 # 除数の型が間違っています
トレースバック (最近の呼び出し履歴):
  ファイル "<stdin>", 1行目, <モジュール> 内
TypeError: / 演算子に対するサポートされていないオペランドの型: 'int' と 'str'


14) ZeroDivisionError:ゼロで除算した場合。

>>> 12 / 0
トレースバック (最近の呼び出し履歴):
  ファイル "<stdin>", 1行目, <モジュール> 内
ZeroDivisionError: ゼロで除算しました


15) IOError:入出力操作エラー。たとえば、存在しないファイルを開こうとした場合。

>>> def io_except_demo():
...     try:    # 存在しないファイルを開く
...             fd = open("non_exist_file.txt", "r")
...     except IOError, except_obj:
...             print("IOError 例外が発生しました")
...     else:
...             print("例外は発生しませんでした")    # 例外がなければこのブランチが実行されます
...
>>> io_except_demo()
IOError 例外が発生しました         # 5行目の出力


post
  • 7

    item of content
例外処理は現代のプログラミング言語の基本的な特性でもあり、正常な分岐と例外の分岐を切り分けることができます。C言語とは異なり、正常な分岐と例外の分岐が混在することはありません。
Pythonにおいて例外は特別なオブジェクトであり、この例外オブジェクトを通じて例外発生時の情報を例外処理関数に渡すことができます。
この章では、例外の捕捉方法、例外情報の取得方法、特定の例外の無視、例外のスロー方法、カスタム例外オブジェクトの作成、そしてPython 2とPython 3における例外処理の類似点と相違点について説明します。最後に、一般的なシステム定義の例外についても紹介します。