エラーと例外処理
Pythonでファイルをオープンしようとして、指定したファイルが存在しないとエラーが発生して、プログラムが終了してしまいます。
code: python
>> f = open('dummy.txt')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
FileNotFoundError: Errno 2 No such file or directory: 'dummy.txt' >>
このようなエラーでプログラムが終了しないようにするために例外処理を記述します。
try文 と except文
try文を記述したブロックでエラーが発生すると、except 文がエラーを捉えて、処理を行うことができます。
先の例では、指定したファイルが存在しないために、FileNotFoundError が発生して、プログラムが終了してしまいます。この場合、次のように記述するとプログラムの中で入力エラーとして処理することができるようになります。
code: 0401_error_example.py
data = None
while data == None:
filename = input('Filename: ? ')
try:
f = open(filename)
except IOError:
print('This error occors in python2.x.')
except FileNotFoundError as errmsg:
print(errmsg)
else:
data = f.read()
f.close()
print(data)
except文で複数のエラーを指定することができます。また、as に続けて指定した変数にエラーがエラーオブジェクトとしてセットされます。
try文で表現するブロックは、if文などと同じように複数ネストさせることができます。
ただし、プログラムが読解しづらくなるのでおすすめはしません。
例えば、with文を使ったファイルオープンの挙動を、with文を使わずに例外を使って記述すると次のようになります。
code: 0402_nested_try.py
# あくまで例として記述しています。 withを使いましょう。
f = None
try:
f = open("data.txt")
try:
data = f.read()
except:
print('Read Error')
finally:
if f:
f.close()
例外での else文とfinally文
例外処理で記述する else文で指定したブロック(else節)は、try文で指定するブロック(try節)が正常に終了したときに実行されます。つまり、except文でエラーが捕獲された場合は、else節は実行されません。 これに対して、finally文で指定するブロック(finnally節)はエラーの有無に関係なく常に実行されます。
code: 0403_try_with_else_finaly.py
def my_divide(a, b):
try:
print(a / b)
except ZeroDivisionError as e:
print('ZeroDivisionError:', e)
else:
print(f'ELSE: {a} and {b}')
finally:
print(f'FINISH: {a} and {b}')
my_divide(1,2)
my_divide(1,0)