[光-Hikari-のPython]07章-02 例外処理（例外処理によるプログラムの継続実行）

#[Python]07章-02 例外処理によるプログラムの継続実行
[07章-01](https://qiita.com/ko0821/items/4df28c2d6a2392f9bcb7)では2つの例の例外について取り扱いました。
しかし、前節でも見た通り、例外が発生すると、その場でブログラムが終了してしまいます。このプログラムを継続して処理したり、または継続できなくても画面に例外が発生した旨を通知したりする必要があります。
今回は、例外が発生した際の**例外処理**について説明していきます。

##例外処理の記載
前述した通り、例外が発生すると処理がそのまま中断してしまいます。そのため、中断をさせないために、**別の個所に記載されたプログラムでの処理を実行していく**必要があります。こういった処理を**例外処理**と言います。

例外処理はおおよそ以下のように記述します。

```.py
try:
    例外処理を行いたい場所
except:
    例外を処理する場所
```

実際に、例外処理を記述してみましょう。<font color="#00cccc">chap07</font>の中に<font color="#00cccc">samp07-02-01.py</font>というファイル名でファイルを作成し、以下のコードを書いてください。

```samp07-02-01.py
print('割り算a÷bを求めます。')

try:
    a = int(input('aの値を入力してください：'))
    b = int(input('bの値を入力してください：'))
    print(a / b)
except:
    print('0による除算がおこなわれましたので、処理を終了します。')
```
><font color="#090" bgcolor="black">【実行結果】</font>
割り算a÷bを求めます。
aの値を入力してください：10
bの値を入力してください：0
0による除算がおこなわれましたので、処理を終了します。

今回、**try:**のブロックにおいて、0による除算が行われたため、例外処理が発生します。すると、**except:**ブロックへ飛び、そのブロック内での処理が行われます。

なお、07章-01のときには**try～catch**を記載していなかったため、処理が強制的に中断して赤文字でエラーメッセージが出ていましたが、今回は例外処理が発生しているため、エラーメッセージは出ておりません。

このように、except内では、例外が発生した際の処理を書きます。今回は**print関数**による出力でしたが、「監視端末への通知を行う」、「再度処理を促す」などといったことに使用したりします。

##特定の例外
先ほどは**except**と記載していました。今回は「bに0が代入されるかもしれない」という前提でexcept内には「0による除算がおこなわれましたので、処理を終了します。」と出力していました。

しかし、例外にはほかにもあります。exceptにしてしまうと、0による除算以外での例外も発生する可能性があります。
例えば、入力の際に数値でなく誤って文字を入力してしまうと以下のエラーが出力されます。先ほどのプログラム<font color="#00cccc">samp07-02-01.py</font>の実行結果です。
><font color="#090" bgcolor="black">【実行結果】</font>
割り算a÷bを求めます。
aの値を入力してください：10
bの値を入力してください：<font color="red">z</font>
0による除算がおこなわれましたので、処理を終了します。

これを見てみると、**b**の個所に**'z'**という文字が入っています。これは0による除算の例外ではありません。本来は数値を入力しなければならないところに文字を入れたことによる例外です。

したがって、**except**としてしまうと、どのような例外でも例外処理を実行させてしまいます。
この場合、「0による除算の例外処理」と「文字を入力した際の例外処理」2つ準備する必要があります。これらはそれぞれ特定の例外となり、それぞれに対しての例外処理を実行させる必要があります。

以下のURLを見てみるとわかるのですが、特定の例外がかなりの種類があります。

[https://docs.python.org/ja/3/library/exceptions.html#concrete-exceptions](https://docs.python.org/ja/3/library/exceptions.html#concrete-exceptions)

上記のサイトにも記載がありますが、今回はこの中で、「0による除算の例外処理」が**ZeroDivisionError**、「文字を入力した際の例外処理」が**ValueError**を使用します。
<font color="#00cccc">chap07</font>の中に<font color="#00cccc">samp07-02-02.py</font>というファイル名でファイルを作成し、以下のコードを書いてください。

```samp07-02-02.py
print('割り算a÷bを求めます。')

try:
    a = int(input('aの値を入力してください：'))
    b = int(input('bの値を入力してください：'))
    print(a / b)
except ZeroDivisionError:
#bの値が0出会ったときに行う例外処理
    print('0による除算がおこなわれましたので、処理を終了します。')
except ValueError:
#aまたはbが数値でなかった際に行う例外処理
    print('数値でないデータが入力されましたので処理を終了します。')
```
><font color="#090" bgcolor="black">【実行結果1】</font>
割り算a÷bを求めます。
aの値を入力してください：10
bの値を入力してください：0
0による除算がおこなわれましたので、処理を終了します。

><font color="#090" bgcolor="black">【実行結果2】</font>
割り算a÷bを求めます。
aの値を入力してください：10
bの値を入力してください：z
数値でないデータが入力されましたので処理を終了します。

順に処理を追ってみます。
まず、0による除算の場合の例外について、上記のURLには以下の記載があります。
>exception **ZeroDivisionError**
除算や剰余演算の第二引数が 0 であった場合に送出されます。関連値は文字列で、その演算における被演算子と演算子の型を示します。

最初の【実行結果1】では、**b**の値として0が代入されたため、例外が発生し、ZeroDivisionError側の例外処理が行われます。

>exception **ValueError**
演算子や関数が、正しい型だが適切でない値を持つ引数を受け取ったときや、 IndexError のようなより詳細な例外では記述できない状況で送出されます。

【実行結果2】では、**b**の値として'z'が代入され、除算ができないために例外が発生し、ValueError側の例外処理が行われます。

##演習問題
演習問題を用意しました。ぜひ解いてみてください。プログラムは<font color="00cccc">chap07</font>内に作成してください。使用する変数名は好きな変数名を指定してかまいません。
<font color="3333ff">
【1】[07章-01](https://qiita.com/ko0821/items/4df28c2d6a2392f9bcb7#%E4%BE%8B%E5%A4%96%E3%83%AA%E3%82%B9%E3%83%88%E3%81%AE%E8%A6%81%E7%B4%A0%E3%82%92%E8%B6%85%E3%81%88%E3%81%A6%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%9F%E5%A0%B4%E5%90%88%E3%81%AE%E4%BE%8B%E5%A4%96)で書いた以下のプログラム、</font>

```.py
ls = [1, 3, 5, 7, 9]
print(ls)
i = int(input('上記のリストの要素番号を指定してください：'))

print(ls[i])
```
<font color=#3333ff>について、指定した要素数を超えた際に、例外処理を発生させるプログラムを作成してください。なお、特定の例外を使った方法で作成してください。特定の例外は先ほどの上記あるURLで調べてみましょう。</font>
><font color="#090" bgcolor="black">【実行結果】</font>
[1, 3, 5, 7, 9]
上記のリストの要素番号を指定してください：5
リストの要素を超えて指定しています。

##最後に
例外処理はエラーに強いプログラムを作る方法の1つであることを留めておいてください。例外処理によりプログラムがエラーにならないため、重大なインシデントも防ぐ意味でも、ぜひ身に着けておきましょう。今後もよく登場します。

###[【目次リンク】へ戻る](https://qiita.com/ko0821/items/379e8bd9e6ea01089419)