|
環境設定
プログラム作成
例外
tkinter
|
Python例外 (try — exept)Python の例外 (try — except) の使い方を説明します.この構文を使うと,プログラムの例外処理 (実行時エラー) を簡単に分かりやすく記述することができます.Python っぽいプログラムを書くためには,ぜひ見つけて欲しい知識です. 目次はじめに例外とはプログラムには二種類のエラーがあります.ひとつは文法上のエラーで,シンタックスエラーあるいは構文エラーと呼ばれるもので,定められた構文規則 (文法) を満たしていない時に発生します.通常,これは実行に先立ってチェックされます.もう一方は,実行時エラーです.文法は正しいのですが,実行するとおかしな挙動が起きます.例えば,数値をゼロで割るようなエラーがあります.この実行時のエラーを Python では例外 (exception) と呼びます. 要するに,例外は「プログラムの文法は正しいが,正しく動作しないエラー」です.他のプログラミング言語では実行時エラーと呼ばれるものです. 例外処理が必要な理由多くの例外は,プログラムを使うユーザーの不注意で発生します.これは度々発生するため,プログラマーは「ユーザーが誤った使い方をしてもきちんと動作する」ようにプログラムを作成しなくてはなりません.そのためには,プログラマーが意図していない動作をユーザーが行った場合など,その対策の処理を書きます.Python には例外処理のための構文 (try &mdahs; except) が用意されています. 例外処理を記述することで,プログラムはロバスト (堅牢) になります. 他の言語との比較実行時エラーが起きた場合の処理はプログラミング言語 (あるいはコンパイラー) によって異なります.多くの言語は戻り値で実行時エラーの内容を知らせます.そして,自動的に停止する言語も多いです.実際のプログラムでは,戻り値に応じた処理を記述します.この処理をあちこちに書くことになり,かなりの労力が必要です.これって,かなり大変です.Python には,この実行時エラーを処理する構文 (try — except) があります.この構文を使うことで,プログラムは分かりやすくなります. 以下の例は,実行時エラー (ゼロ割) の処理を記述した Python と C言語のプログラムです. a = 0
try:
b = 123/a
print(b)
except ZeroDivisionError as err:
print('error: ', err)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(){
double a, b;
a = 0;
b = 123/a;
if(b == INFINITY){
printf("error: division by zero\n");
exit(0);
}
else{
printf("%.3e\n", b);
}
return 0;
}
この二つのプログラムは全く同一の結果になります.いずれも実行すると,コンソールに「error: division by zero」と表示されます.Python のプログラムの方が,短くて分かりやすいです.実際のプログラムでは,結構多くの例外処理が必要です.そのため,短くて分かりやすいということはとても大事です. この Python のプログラムは,次のように動作します,
書き方と動作の基本基本例外処理の「try — exept」の書き方を説明します.一般的な書き方は,以下のとおりです.try があるとひとつ以上の except が必要です.else や finally は無くても問題なく実行できます. try: トライで実行する処理を書きます (try 節) ⋮ except 例外名 as 変数: 例外名で指定された例外の処理を書きます (except 節) ⋮ except: これまでにキャッチされていない例外の処理を書きます (except 節) ⋮ else: 例外が発生しなかった場合の処理を書きます (else 節) ⋮ finally: 例外の有無にかかわら実行される処理を書きます (finally 節) ⋮ このようにプログラムを書くと,try 節が実行されます.そこで例外の発生の有無によって動作が異なります.具体的には:
です.注意すべきことは,(1) try 節で例外が発生したらその節の以降の行の命令は実行されない,(2) except 節は最初に例外にマッチしたもののみ実行される,ことです.あとはプログラムを見ての想像のとおりです. 例外に関わるコマンドの書き方は,以下のとおりです.
例外の送出 (raise)例外を送出 (raise) には,二通りの方法 (自動送出,明示的送出) があります.自動送出では,Python に組み込まれた関数 (メソッド) で例外が発生すると自動的に搬出します.ユーザーはそれをキャッチする except 節を書くだけです.明示的に送出するには,ユーザープログラムで例外を送出するコマンド「raise 例外名」を記載します.例外名には予め用意されている組み込み例外とユーザーが作成するカスタム例外の二通りがあります. ここでは,三個の具体的なプログラムを用いて例外の送出の方法を示します.いずれのプログラムの動作は,全く同一で,1行毎にファイルの内容を読み込んで表示します.ファイルが無かった場合,例外を送出します.そして,except 節で例外をキャッチし,エラーメッセージを表示し,プログラムを終了します. 自動送出Python の組み込み関数 (メソッド) は自動的に組み込み例外を送出する機能を持っているものがあります.関数の例外送出は,マニュアルに記載があります.例外の自動送出の機能がある場合は,ユーザーが明示的に例外の送出 (raise) を記述する必要はありません.以下のプログラムでは,例外があると自動的に組み込み例外: OSError が送出されます. try:
file_path = input('ファイル名: ')
with open(file_path, 'r') as f:
for line in f:
print(line, end='')
except OSError as err:
print(err)
組み込み例外を明示的に送出コマンド raise を使うと明示的に例外を送出することができます.以下の例は,組み込み例外を送出 (raise) するプログラムです.ファイルの有無をチェックして,ファイルが無い場合は組み込み例外: ValueError を送出します. import os.path
try:
file_path = input('ファイル名: ')
ret = os.path.isfile(file_path)
if not ret:
raise ValueError('ファイルがありません') # 組み込み例外送出
except ValueError as err:
print(err)
else:
with open(file_path, 'r') as f:
for line in f:
print(line, end='')
組み込みの例外を送出のコマンドは カスタム例外の作成と送出次は,ユーザーが作成したカスタム例外の例です.カスタム例外と言っても難しくはありません.メンバー関数 (メソッド) に,__init__ と __str__ を記述するだけです. import os.path
class CustomException(Exception): ### カスタム例外の定義のクラス
''' カスタム例外です '''
def __init__(self, value):
self.parameter = value
def __str__(self):
return repr(self.parameter)
class PrintFile():
''' ファイルを読んでディスプレイに出力します '''
def __init__(self, file):
self.file_path = file
def out_display(self):
if not os.path.isfile(self.file_path):
raise CustomException('ファイルがありません') ### カスタム例外送出
with open(self.file_path, 'r') as f:
for line in f:
print(line, end='')
if __name__ == '__main__':
try:
file_path = input('ファイル名: ')
PrtFl = PrintFile(file_path)
PrtFl.out_display()
except CustomException as err:
print(err)
else:
del PrtFl
このプログラムのクラス「CustomException(Exception)」がカスタム例外です.カスタム例外の書き方の基本は以下のとおりです.
カスタム例外のクラスを作成したら,使い方は組み込み例外と全く同じです. 例外のキャッチ (except) の順番例外のクラス (オブジェクト) に親子関係がある場合には注意が必要です.子のオブジェクトが例外を送出した場合,親のクラス名も例外としてキャッチされます.具体的には,以下のカスタムの例外のプログラムで説明します. [注意] 以下のカスタム例外 (A, B, C) は __init__ も __str__ も無い,最も単純な例です.例外の名前があるだけですが,きちんと動作します. class A(Exception): # Exception を継承
pass
class B(A): # Exception > A を継承
pass
class C(B): # Exception > A > B を継承
pass
for test_class in [A(), B(), C()]:
try:
raise test_class
except C:
print('C', end='')
except B:
print('B', end='')
except A:
print('A', end='')
このプログラムを実行すると「ABC」と表示されます.もし「except A:」を最初に記述すると,実行結果は「AAA」となります.この動作は,親のクラス名も例外として送出されることと,最初にキャッチした例外のみが実行されることを考えると,理解できます. 以上の例で分かるように,例外処理を記述する場合,except 節の順番が重要です.子プロセスから親プロセスの順番に記述しなくてはなりません.誤って親プロセスの例外を先に記述すると,子プロセスの例外が実行されることはありません.組み込み例外の親子関係 (階層) は「組み込み例外」に示します. 全ての例外をキャッチする「except:」はプログラムに最後に記述します.途中に記述すると,それ以降の except 節は実行されることが無いからです. プログラム例組み込み例外キー入力のチェック整数のキー入力を要求するプログラムです.整数以外の入力があると,例外が発生します. while True:
try:
x = int(input("Please enter a number: "))
except ValueError as err:
print(err)
print("入力は整数だよ.もう一度")
else:
print(x)
break
カスタム (ユーザー作成) 例外なにか良い例を思いついたら追記します. 組み込み例外 (階層と内容)以下に,組み込み例外の階層 (ツリー) を示します.
ページ作成情報参考資料更新履歴
|