【ValueErrorをハンドリングしよう!】例外処理を解説

今回の記事では、ValueErrorを使って例外・エラー処理について説明致します!

「例外って何?」
「例外をどうやってキャッチすればいいの?」
「例外が発生した時にきまったメッセージを表示させたい」

という方へ向けて、


【基礎】例外とは
【基礎】ValueErrorとは
【基礎】例外をキャッチする方法
【応用】任意のエラーメッセージを表示させる方法
【応用】複数のエラーが予想される場合の対処法

について解説致します。

この記事を読んでいただければ、ValueErrorについてと例外の基礎を理解する事ができます。

ぜひ、最後までお付き合いください。

※ この記事のコードはPython 3.7, Ubuntu 18.04で動作確認しました。

本記事を読む前に、Pythonがどんなプログラミング言語なのかをおさらいしておきたい人は次の記事を参考にしてください。

→ Pythonとは?特徴やできること、活用例をわかりやすく簡単に解説

なお、その他のPythonの記事についてはこちらにまとめています。

目次

例外とは

まずはじめに、例外について説明致します。

例外とは、関数を呼び出した場合に発生するエラーのことを指します。

プログラムを書き、それをコンパイルして出るエラーはコンパイルエラーと言います。

それに対し、コンパイルは正常にできたうえでプログラムを実行した時に発生するエラーが例外です。

ここで例外の一種を紹介します。

num = 10 / 0
print("{0}".format(num))

こちらはコンパイル時にはエラーが発生しません。

しかし、これを実行すると

実行結果:

ZeroDivisionError: integer division or modulo by zero

ZeroDevisionErrorが発生していますね。

これが例外です。

今回の例に挙げたZeroDevisionErrorはゼロ除算と言って、ある数をゼロで割ろうとする時に出る最も知られている例外の一つです。

プログラムの構文自体は正しいのに、実行時に発生してしまうエラーのことを例外といいます。

以降ではその他の例外の一種であるValueErrorを例として紹介致します。

ValueErrorとは

ValueErrorとは、引数の型はあっているけれど誤った値を取っている場合に発生する例外です。

例をいくつか紹介します。

num = "zero"

Div = 10 / int(num)
print("{0}".format(num))

実行結果:

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

上記の例では、型はintに変換されている為正しいですが、値が「zero」となってしまっている為計算ができずValueErrorとなっています。

以下のような場合もあります。

import math

num = -1.0

math.log(num)

実行結果:

ValueError: math domain error

この例では値は数になっていて正しいですが、math.log()は負数を扱う事ができません。

そのため、値の範囲外となってしまい「ValueError: math domain error」となってしまいます。

このように引き渡す値が間違っている時に出るエラーがValueErrorです。

例外をキャッチする方法

例外、とりわけValueErrorについてわかったところで、この例外を処理する方法を紹介致します。

まずはじめに、例外をキャッチする方法を確認しましょう。

例外をキャッチする事で、例外が発生した後の処理についても任意に設定する事ができます。

やり方はtry-exceptという方法を使い、エラーが発生しそうな箇所に”try”と”except”を記述する事で実装します。

実際の例をご確認ください。

num = "zero"

try:
    Div = 10 / int(num)
except ValueError:
    pass

print ("num: " + num)

このように実装する事で、例外をキャッチする事ができます。

ポイントは以下2点です。
1. try: の後に例外が発生しそうな処理を書く
2. except:の横に発生し得るエラーを記述し、次の行にエラー発生時の処理を記述する

このようにする事で、エラーが発生した時に任意の処理を行う事ができます。

また、例外をキャッチしない場合は例外が発生した時点で処理が中断されてしまいますが、今回のようにキャッチができていると処理を終了せず次の処理に入ります。

実行結果:

num: zero

1点気をつけていただきたいのですが、exceptに記述した例外とは別の例外が発生した場合はキャッチできないので、処理が終了しますのでご注意ください。

また、try-exceptでエラーを握りつぶすのはあまりいい方法ではありません。適切なエラーハンドリング(エラー処理)を行うことが重要です。

エラーをハンドリングする方法

例外のキャッチの方法がわかったところで、エラーが発生した時のハンドリングの方法について確認しましょう。

返ってきたエラーメッセージを表示する方法

まずはじめに、例外が発生した時に処理は中断させたくないけれど、例外を出力したい場合は以下のように実装します。

num = "zero"
 
try:
    Div = 10 / int(num)
except ValueError as error:
    print(error)

print("num: " + num)

実行結果:

invalid literal for int() with base 10: 'zero'
num: zero

ValueErrorの次に「as エラー名」と記述する事で、そこにエラーを代入する事ができます。

この時の受け取るエラーの型を確認すると、「<type ‘exceptions.ValueError’>」となっています。

エラーメッセージとしての文字列型ではないので要注意です。

また、except後のprint()に任意のエラーメッセージを記述する事も可能です。

複数のエラーが予想される場合の対処法

続いてはエラーの種類によって処理を切り替える方法を紹介します。

実際の例をご確認ください。

def division(num1, num2):
    try:
        #エラーが発生していない場合の処理
        Div = int(num1) / int(num2)
        return Div
    except ValueError as error:
        #ValueErrorの時の処理
        return "ValueError: 正しい値を入れてください"
    except ZeroDivisionError:
        #ZeroDivisionErrorの時の処理
        return "ZeroDivisionError: 第2引数に0が入力されました"

print(division(10, "zero"))
print(division(10, 0))
print(division(10, 5))

実行結果:

ValueError: 正しい値を入れてください
ZeroDivisionError: 第2引数に0が入力されました
2

このようにして、正常時とそれぞれの例外が発生した時によって処理を分ける事ができます。

まとめ

いかがでしたでしょうか?

今回の記事では、


【基礎】例外とは
【基礎】ValueErrorとは
【基礎】例外をキャッチする方法
【応用】任意のエラーメッセージを表示させる方法
【応用】複数のエラーが予想される場合の対処法

について紹介致しました。

例外についてきちんと理解すると、すぐに中断されない柔軟なアプリケーションを作る事ができます。

この記事を基礎にして、ぜひ例外処理マスターを目指してください!

この記事を書いた人

1991年生まれ。双子座。
理系大学で認証システムを学んだ後、アプリ開発者となる。
新しく学ぶ人に寄り添った記事を心がけて執筆します。
芸術が好き。いつか猫と暮らすのが夢。

目次