このページで解説している内容は、以下の YouTube 動画の解説で見ることができます。

【Python入門】例外処理とは

例外処理とは

 プログラムを動かしている間に、想定外の値を受け取ったり実行不可能な処理が生じたりすると、しばしば「例外」と呼ばれるエラー状態が発生します。Pythonをはじめ多くの言語では、こうした問題を検知してプログラムに通知する仕組み(例外機構)があります。例外の対処コードを記述せずに無視すると、プログラムが途中で強制終了してしまいますが、適切に例外処理を行うことで、その後の正常な処理を続行することが可能です。ここでは、例外とは何か、そしてどのような状況で発生し得るのかを解説します。

プログラムのダウンロード

 「ダウンロード」から、JupyterLab で実行できるサンプルプログラムがダウンロードできます。ファイルは、ESET Endpoint Securityでウイルスチェックをしておりますが、ダウンロードとプログラムの実行は自己責任でお願いいたします。

1.例外とは

1.1. 望ましくない事態の通知

 「例外」とは、プログラムが実行される途中で発生するさまざまなトラブルのことです。たとえば、ユーザーが数値を入力するように促された場面で文字列や小数が入力されたり、0で割り算しようとしたりすると、通常の処理を続行できない問題が起こります。こうした事態を例外として言語処理系が検知し、開発者に通知することで、必要に応じた対処(エラーの表示や再入力の促しなど)を行えます。

1.2. 例外を処理しないとどうなるか

 例外が発生しても、その対処方法をプログラム内で明確にしていない場合は、通常エラーメッセージを表示して強制終了してしまいます。つまり、途中でプログラムが止まる ことになるため、ユーザーにとっては使い勝手が悪く、開発者にとっては後処理やログの記録などが行えない状態になる可能性があります。そこで、事前に「もしこうした例外が発生した場合はこう動作する」という処理を用意し、例外が発生してもアプリケーションを継続できるようにするのが「例外処理」の目的です。

2.実行中によく起こる例外の例

 ここでは、簡単なユーザー入力を元に演算を行うコードを例にしながら、どのような例外が発生し得るかを確認してみます。以下のプログラムでは、distance(移動距離)とpeople(人数)をそれぞれ入力し、距離を人数で割った整数値を表示します。次の処理手順の通りに無限ループ(while True)で繰り返すことで、何度でも同じ計算が行える仕組みです。

while True:
    distance = int(input('distance: '))
    people = int(input('people: '))
    print('distance//people =', distance // people)
    print('-' * 25)  # 区切りとして25個のハイフンを表示

実行結果1:peopleに「文字列」を入力

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[1], line 2
      1 while True:
----> 2     distance = int(input('distance: '))
      3     people = int(input('people: '))
      4     print('distance//people =', distance // people)

ValueError: invalid literal for int() with base 10: 'abc'

実行結果2:peopleに「0」を入力

---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
Cell In[3], line 4
      2 distance = int(input('distance: '))
      3 people = int(input('people: '))
----> 4 print('distance//people =', distance // people)
      5 print('-' * 25)

ZeroDivisionError: integer division or modulo by zero

詳しい解説

  1. while True: で無限ループを開始。Ctrl + Cなど(JyupyterLabでは■ボタン)で手動終了します。
  2. input 関数で「distance: 」という文字列を表示し、ユーザーからの入力を distance に受け取り、int 関数で整数に変換します。
  3. 同様に「people: 」という表示とともに入力を受け取り、people を整数に変換します。
  4. distance // people で整数除算の結果を計算し、print 関数で表示します。
  5. 仕切りとして print('-'*25) により ------------------------- を出力して、次の計算に備えます。

2.1. 数値以外の入力によるValueError

 上記のプログラムで、distance に「abc」などの文字を入力してみると、int('abc') の変換が行えず ValueError が発生します。同様に浮動小数点数「3.14」を入力した場合も、やはり int 関数に変換できず ValueError が起こります。このエラーは「数値型への変換が失敗した」ことを意味し、処理を継続できずプログラムが終了する原因となります。

2.2. 0による除算によるZeroDivisionError

 次に distance として 100 などの整数を入力し、people に 0 を入力すると、distance // people の計算で「0で割り算を行う」ことになり、ZeroDivisionError が発生します。これは「割り算で除数として0が指定されたとき」の典型的なエラーで、Pythonを含むほとんどの言語でエラーとして扱われます。

以下の表は、今回の例で発生した例外の種類とその発生条件を示しています。

例外の種類発生条件例外メッセージ例
ValueError数値に変換できない文字列が入力された場合invalid literal for int() with base 10: 'abc'
ZeroDivisionError除算時に除数が0の場合integer division or modulo by zero

 以上のように、ほんの数行のプログラムでも、ユーザーの入力によってはエラーとなってしまうケースがいくつもあります。次のコンテンツ以降では、こうした例外を適切に処理し、強制終了を防いでプログラムを継続できるようにする「例外処理」の記述方法を詳しく見ていきます。

まとめ

  • 例外とは、プログラムが正常に実行し続けることを妨げる事態の通知機構。
  • Pythonでは、ValueErrorZeroDivisionError など、さまざまな例外が発生する可能性がある。
  • 例外処理を明示的に記述しないと、プログラムは例外発生時に強制終了してしまう。
  • ユーザー入力など、外部要因のある処理では特に例外を意識した設計が重要。

 次のステップでは、tryexcept といったキーワードを使いながら、どのようにエラーを捕捉し、エラー発生後もプログラムを継続させるかを紹介していきます。