exceptions – ビルトインエラークラス¶
目的: | 例外モジュールはインタープリタや標準ライブラリで使用されるビルトインエラーを定義する |
---|---|
利用できるバージョン: | 1.5 以上 |
説明¶
これまでに Python はクラス同様に例外として単純な文字列のメッセージに対応していました。Python 1.5 以降、全ての標準ライブラリモジュールはクラス例外を使用します。Python 2.5 を使用すると文字列例外は DeprecationWarning を発生させます。そして、文字列例外のサポートは今後廃止される予定です。
ベースクラス¶
例外クラスは階層構造で定義されていて、標準ライブラリドキュメントに説明があります。明らかな階層化の利点に加えて、継承された例外のベースクラスを捕捉することで関連する例外をまとめて捕捉できるので例外の継承は役に立ちます。大半のケースでは、ベースクラスは直接発生させることを目的としていません。
BaseException¶
全ての例外のベースクラスです。そのコンストラクタへ渡される引数から str() を使用してその例外の説明メッセージを作成するロジックを実装してください。
Exception¶
実行中のアプリケーションを終了させない例外のためのベースクラスです。全てのユーザ定義の例外はベースクラスとして Exception を使用すべきです。
StandardError¶
ビルトイン例外のベースクラスは標準ライブラリで使用されます。
ArithmeticError¶
数値関連のエラーのためのベースクラスです。
LookupError¶
何かを発見したときに発生させるエラーのベースクラスです。
EnvironmentError¶
Python の外部(オペレーティングシステム、ファイルシステム等)から発生するエラーのためのベースクラスです。
例外を発生させる¶
AssertionError¶
assert 文が失敗したときに AssertionError が発生します。
assert False, 'The assertion failed'
$ python exceptions_AssertionError_assert.py
Traceback (most recent call last):
File "exceptions_AssertionError_assert.py", line 12, in <module>
assert False, 'The assertion failed'
AssertionError: The assertion failed
failIf() のようなメソッドで unittest モジュールでも使用されます。
import unittest
class AssertionExample(unittest.TestCase):
def test(self):
self.failUnless(False)
unittest.main()
$ python exceptions_AssertionError_unittest.py
F
======================================================================
FAIL: test (__main__.AssertionExample)
----------------------------------------------------------------------
Traceback (most recent call last):
File "exceptions_AssertionError_unittest.py", line 17, in test
self.failUnless(False)
AssertionError: False is not true
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (failures=1)
AttributeError¶
属性の参照か割り当てが失敗したときに AttributeError が発生します。例えば、存在しない属性を参照しようとしたときに発生します。
class NoAttributes(object):
pass
o = NoAttributes()
print o.attribute
$ python exceptions_AttributeError.py
Traceback (most recent call last):
File "exceptions_AttributeError.py", line 16, in <module>
print o.attribute
AttributeError: 'NoAttributes' object has no attribute 'attribute'
又は読み込み専用属性を変更しようとしたときに発生します。
class MyClass(object):
@property
def attribute(self):
return 'This is the attribute value'
o = MyClass()
print o.attribute
o.attribute = 'New value'
$ python exceptions_AttributeError_assignment.py
This is the attribute value
Traceback (most recent call last):
File "exceptions_AttributeError_assignment.py", line 20, in <module>
o.attribute = 'New value'
AttributeError: can't set attribute
EOFError¶
input() 又は raw_input() のようなビルトイン関数が入力ストリームの最後に遭遇する前にデータを読み込めないときに EOFError が発生します。 read() のような file メソッドはファイルの最後で空文字列を返します。
while True:
data = raw_input('prompt:')
print 'READ:', data
$ echo hello | python PyMOTW/exceptions/exceptions_EOFError.py
prompt:READ: hello
prompt:Traceback (most recent call last):
File "PyMOTW/exceptions/exceptions_EOFError.py", line 13, in <module>
data = raw_input('prompt:')
EOFError: EOF when reading a line
FloatingPointError¶
浮動小数点例外制御(fpectl)がオンのとき、最終的にエラーを引き起こす浮動小数点の操作で発生します。 fpectl を有効にするには --with-fpectl フラグをセットしてコンパイルされたインタープリタが必要です。 fpectl を使用することは 標準ライブラリドキュメントでは推奨されていません 。
import math
import fpectl
print 'Control off:', math.exp(1000)
fpectl.turnon_sigfpe()
print 'Control on:', math.exp(1000)
GeneratorExit¶
ジェネレータの close() メソッドが呼ばれるときにジェネレータ内部で発生します。
def my_generator():
try:
for i in range(5):
print 'Yielding', i
yield i
except GeneratorExit:
print 'Exiting early'
g = my_generator()
print g.next()
g.close()
$ python exceptions_GeneratorExit.py
Yielding 0
0
Exiting early
IOError¶
入力や出力が失敗するときに発生します。例えば、ディスクがいっぱいだったり、入力ファイルが存在しないときに発生します。
f = open('/does/not/exist', 'r')
$ python exceptions_IOError.py
Traceback (most recent call last):
File "exceptions_IOError.py", line 12, in <module>
f = open('/does/not/exist', 'r')
IOError: [Errno 2] No such file or directory: '/does/not/exist'
ImportError¶
あるモジュール、又はモジュールのメンバがインポートできないときに発生します。ImportError が発生する個所には複数の条件があります。
- モジュールが存在しない場合
import module_does_not_exist
$ python exceptions_ImportError_nomodule.py
Traceback (most recent call last):
File "exceptions_ImportError_nomodule.py", line 12, in <module>
import module_does_not_exist
ImportError: No module named module_does_not_exist
- from X import Y が使用されてモジュール X の内部で Y が見つからなかった場合
from exceptions import MadeUpName
$ python exceptions_ImportError_missingname.py
Traceback (most recent call last):
File "exceptions_ImportError_missingname.py", line 12, in <module>
from exceptions import MadeUpName
ImportError: cannot import name MadeUpName
IndexError¶
IndexError はシーケンスの範囲外を参照したときに発生します。
my_seq = [ 0, 1, 2 ]
print my_seq[3]
$ python exceptions_IndexError.py
Traceback (most recent call last):
File "exceptions_IndexError.py", line 13, in <module>
print my_seq[3]
IndexError: list index out of range
KeyError¶
同様に KeyError は辞書のキーが見つからなかったときに発生します。
d = { 'a':1, 'b':2 }
print d['c']
$ python exceptions_KeyError.py
Traceback (most recent call last):
File "exceptions_KeyError.py", line 13, in <module>
print d['c']
KeyError: 'c'
KeyboardInterrupt¶
ユーザが実行中のプログラムを停止するために Ctrl-C (又は Delete) を押下すると KeyboardInterrupt が発生します。その他のほとんどの例外と違い、Exception を捕捉するグローバルな例外ハンドラによって捕捉されないように KeyboardInterrupt は BaseException から直接継承します。
try:
print 'Press Return or Ctrl-C:',
ignored = raw_input()
except Exception, err:
print 'Caught exception:', err
except KeyboardInterrupt, err:
print 'Caught KeyboardInterrupt'
else:
print 'No exception'
プロンプトで Ctrl-C を押下すると KeyboardInterrupt 例外を引き起こします。
$ python exceptions_KeyboardInterrupt.py
Press Return or Ctrl-C: ^CCaught KeyboardInterrupt
MemoryError¶
実行中のプログラムがメモリ不足になったら、MemoryError を発生させてリカバリ(例えば、オブジェクトを削除する)することができます。
import itertools
# 大量のメモリを割り当てることで MemoryError の発生を試みる
l = []
for i in range(3):
try:
for j in itertools.count(1):
print i, j
l.append('*' * (2**30))
except MemoryError:
print '(error, discarding existing list)'
l = []
$ python exceptions_MemoryError.py
python(49670) malloc: *** mmap(size=1073745920) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
python(49670) malloc: *** mmap(size=1073745920) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
python(49670) malloc: *** mmap(size=1073745920) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
0 1
0 2
0 3
(error, discarding existing list)
1 1
1 2
1 3
(error, discarding existing list)
2 1
2 2
2 3
(error, discarding existing list)
NameError¶
カレントスコープに存在しない名前を参照するときに NameErrors が発生します。例えば、資格のない変数名です。
def func():
print unknown_name
func()
$ python exceptions_NameError.py
Traceback (most recent call last):
File "exceptions_NameError.py", line 15, in <module>
func()
File "exceptions_NameError.py", line 13, in func
print unknown_name
NameError: global name 'unknown_name' is not defined
NotImplementedError¶
サブクラスで定義する必要のあるメソッド又は振る舞いを表すために、 インタフェース を模倣してユーザ定義のベースクラスは NotImplementedError を発生させます。
class BaseClass(object):
"""Defines the interface"""
def __init__(self):
super(BaseClass, self).__init__()
def do_something(self):
"""The interface, not implemented"""
raise NotImplementedError(self.__class__.__name__ + '.do_something')
class SubClass(BaseClass):
"""Implementes the interface"""
def do_something(self):
"""really does something"""
print self.__class__.__name__ + ' doing something!'
SubClass().do_something()
BaseClass().do_something()
$ python exceptions_NotImplementedError.py
SubClass doing something!
Traceback (most recent call last):
File "exceptions_NotImplementedError.py", line 27, in <module>
BaseClass().do_something()
File "exceptions_NotImplementedError.py", line 18, in do_something
raise NotImplementedError(self.__class__.__name__ + '.do_something')
NotImplementedError: BaseClass.do_something
See also
abc - 抽象基底クラス
OSError¶
OSError は os モジュールのエラークラスとして OS に特化した機能からエラーが返されるときに発生します。
import os
for i in range(10):
print i, os.ttyname(i)
$ python exceptions_OSError.py
0 /dev/ttys049
1
Traceback (most recent call last):
File "exceptions_OSError.py", line 15, in <module>
print i, os.ttyname(i)
OSError: [Errno 25] Inappropriate ioctl for device
OverflowError¶
数値の操作が変数のデータ型の最大値を超えるときに OverflowError が発生します。long int は巨大な値のためにより多くの領域を割り当てます。そのため、最終的には MemoryError が発生します。浮動小数点の例外は標準化されていないので浮動小数はチェックされません。必要に応じて普通の int 型から long 型へ変換されます。
import sys
print 'Regular integer: (maxint=%s)' % sys.maxint
try:
i = sys.maxint * 3
print 'No overflow for ', type(i), 'i =', i
except OverflowError, err:
print 'Overflowed at ', i, err
print
print 'Long integer:'
for i in range(0, 100, 10):
print '%2d' % i, 2L ** i
print
print 'Floating point values:'
try:
f = 2.0**i
for i in range(100):
print i, f
f = f ** 2
except OverflowError, err:
print 'Overflowed after ', f, err
$ python exceptions_OverflowError.py
Regular integer: (maxint=9223372036854775807)
No overflow for <type 'long'> i = 27670116110564327421
Long integer:
0 1
10 1024
20 1048576
30 1073741824
40 1099511627776
50 1125899906842624
60 1152921504606846976
70 1180591620717411303424
80 1208925819614629174706176
90 1237940039285380274899124224
Floating point values:
0 1.23794003929e+27
1 1.53249554087e+54
2 2.34854258277e+108
3 5.5156522631e+216
Overflowed after 5.5156522631e+216 (34, 'Result too large')
ReferenceError¶
ガベージコレクトされたオブジェクトへ weakref プロキシを使用してアクセスするときに ReferenceError が発生します。
import gc
import weakref
class ExpensiveObject(object):
def __init__(self, name):
self.name = name
def __del__(self):
print '(Deleting %s)' % self
obj = ExpensiveObject('obj')
p = weakref.proxy(obj)
print 'BEFORE:', p.name
obj = None
print 'AFTER:', p.name
$ python exceptions_ReferenceError.py
BEFORE: obj
(Deleting <__main__.ExpensiveObject object at 0x1004704d0>)
AFTER:
Traceback (most recent call last):
File "exceptions_ReferenceError.py", line 26, in <module>
print 'AFTER:', p.name
ReferenceError: weakly-referenced object no longer exists
RuntimeError¶
他に適切な例外がないときに RuntimeError 例外が使用されます。インタープリタはこの例外を滅多に発生させませんが、ユーザコードによっては RuntimeError を発生させます。
StopIteration¶
イテレータが終了したときに、そのイテレータの next() メソッドは StopIteration を発生させます。この例外はエラーと見なされません。
l=[0,1,2]
i=iter(l)
print i
print i.next()
print i.next()
print i.next()
print i.next()
$ python exceptions_StopIteration.py
<listiterator object at 0x100460650>
0
1
2
Traceback (most recent call last):
File "exceptions_StopIteration.py", line 19, in <module>
print i.next()
StopIteration
SyntaxError¶
パーサが解析できないソースコードを見つけたときに SyntaxError が発生します。この例外はモジュールのインポート、 exec を実行したり、 eval() を呼び出したりするときに発生する可能性があります。例外の属性はこの例外を引き起こしたのがソースコードのどのテキストなのかを厳密に見つけるために使用されます。
try:
print eval('five times three')
except SyntaxError, err:
print 'Syntax error %s (%s-%s): %s' % \
(err.filename, err.lineno, err.offset, err.text)
print err
$ python exceptions_SyntaxError.py
Syntax error <string> (1-10): five times three
invalid syntax (<string>, line 1)
SystemError¶
インタープリタそのものでエラーが発生しても正常に実行を継続する可能性があるときに SystemError が発生します。SystemErrors は、おそらくはインタープリタのバグを表し、メンテナへ報告すべきです。
SystemExit¶
sys.exit() が呼び出されるとき、即時終了する代わりに SystemExit が発生します。これは try:finally ブロックのクリーンアップコードの実行、例外を捕捉するための(デバッガやテストフレームワークのような)特別な環境や処理を終了させないようにします。
TypeError¶
誤ったオブジェクトのデータ型を結合する、又は誤ったオブジェクトのデータ型で関数を呼び出すことで TypeErrors が発生します。
result = ('tuple',) + 'string'
$ python exceptions_TypeError.py
Traceback (most recent call last):
File "exceptions_TypeError.py", line 12, in <module>
result = ('tuple',) + 'string'
TypeError: can only concatenate tuple (not "str") to tuple
UnboundLocalError¶
UnboundLocalError はローカル変数の名前に特化した NameError の一種です。
def throws_global_name_error():
print unknown_global_name
def throws_unbound_local():
local_val = local_val + 1
print local_val
try:
throws_global_name_error()
except NameError, err:
print 'Global name error:', err
try:
throws_unbound_local()
except UnboundLocalError, err:
print 'Local name error:', err
グローバルな NameError と UnboundLocal の違いはその名前の使用方法です。”local_val” という名前が式の左側に現れるのでローカル変数の名前として解釈されます。
$ python exceptions_UnboundLocalError.py
Global name error: global name 'unknown_global_name' is not defined
Local name error: local variable 'local_val' referenced before assignment
UnicodeError¶
UnicodeError は ValueError のサブクラスでユニコードに関する問題で発生します。さらに UnicodeEncodeError, UnicodeDecodeError や UnicodeTranslateError といったサブクラスに分割されます。
ValueError¶
ある関数の受け取る値が正しい型で不正な値を持つときに ValueError が発生します。
print chr(1024)
$ python exceptions_ValueError.py
Traceback (most recent call last):
File "exceptions_ValueError.py", line 12, in <module>
print chr(1024)
ValueError: chr() arg not in range(256)
ZeroDivisionError¶
除算の分母がゼロのとき ZeroDivisionError が発生します。
print 1/0
$ python exceptions_ZeroDivisionError.py
Traceback (most recent call last):
File "exceptions_ZeroDivisionError.py", line 12, in <module>
print 1/0
ZeroDivisionError: integer division or modulo by zero
警告のカテゴリ¶
warnings モジュールと一緒に使用する複数の例外もあります。
- Warning
- 全ての warnings のベースクラス
- UserWarning
- ユーザコードから返される warnings のベースクラス
- DeprecationWarning
- 今後はメンテナンスされない機能に使用される
- PendingDeprecationWarning
- すぐに廃止予定の機能に使用される
- SyntaxWarning
- 怪しい構文に使用される
- RuntimeWarning
- 実行時に問題を引き起こすかもしれないイベントに使用される
- FutureWarning
- 言語又はライブラリがその後に変更されることに関して警告する
- ImportWarning
- モジュールインポートの問題に関して警告する
- UnicodeWarning
- ユニコードテキストの問題に関して警告する
See also
- exceptions
- 本モジュールの標準ライブラリドキュメント
- warnings
- エラーではない警告メッセージ