Python ユーザー定義例外 User defined Exceptions

Python学習【365日チャレンジ!】65日目のマスターU(@Udemy11)です。

お腹が空くとついついお菓子を食べてしまうので、体重が増加気味です。

ダイエットをしようと思ってもなかなか運動をする気にならず、Python学習をしようとMacBookProの前に座ってしまうので、どんどん運動から遠ざかっているような気がします。

なので、できることといえば、食べる量を減らすことなんですが、食べる量を減らすとお腹が空いて集中力が持たないんですよね。

そんなトレードオフを考えながら、今日もPython学習にいそしみました。

昨日の復習

昨日は、例外処理を学習しました。

try-except文やtry-except-else文、finally文などがあり、エラーの種類に対して実行する内容を変えたりして、エラー処理をコントロールできました。

l = [10, 20, 30]

try:
    print(l[2])
except NameError as ex:
    print('Error occurred {}', format(ex))
except IndexError as ex:
    print('Error occurred {}', format(ex))
else:
    print('Finish')
finally:
    print('Clean up')

出力結果

30
Finish
Clean up

exceptNameErrorIndexErrorをキャッチして、Error occurred エラーの名前と表示させて最後にClean upを表示させるか、正常にtry文が終了したら、Finishを出力して最後にClean upを表示させるコードです。

このコードの場合は、指定した2つのエラーが起こっても処理を中断することはありませんが、他のエラーが起こると処理が中断されます。

ただし、finally文は、エラーが起こる起こらないに関わらず実行されるので、Clean upは必ず出力されます。

例外処理の基本はこちらのエントリーをごらんください。

今日は、ユーザー定義の例外処理を学習します。

ユーザー定義例外とは

例外(エラー)の多くはExceprionクラスに含まれていて、ユーザーが定義する例外もこのクラスから派生させるべきだという文言がPythonの公式ドキュメントに記載されています。

また、公式ドキュメントには、ユーザー定義例外の作り方も載っているのですが、今の私のレベルで読み解くことができたのは、ユーザー定義例外は単純なものにしておくことが推奨されているということくらいです。

様々なプログラムを書く中で、組み込み例外以外の例外を作ってチェックする場面が出てくるようですので、いまは使い方がわからないまでも、こんなことができるということを頭の片隅に残しておきましょう。

ユーザー定義例外の書き方

ユーザー定義例外の書き方は簡単で、次の3つのコードで処理することができます。

  • classでエラー名を決めてExceptionを指定する
  • 何もしないという意味のpassclassを閉じる
  • raiseでエラー(ユーザー定義例外)を呼び出す
  • 実際のやり方をみてみましょう

    class LowerError(Exception):
        pass
    
    def check_word():
        words = ['iPad', 'iPhone', 'macbook']
        for word in words:
            if word.islower():
                raise LowerError(word)
    
    check_word()

    出力結果

    Traceback (most recent call last):
      File "/private/var/mobile/Containers/Shared/AppGroup/BA3519D5-E394-4ECC-BFF6-B1876836D55A/Pythonista3/Documents/Mypython/day0415.py", line 11, in <module>
        check_word()
      File "/private/var/mobile/Containers/Shared/AppGroup/BA3519D5-E394-4ECC-BFF6-B1876836D55A/Pythonista3/Documents/Mypython/day0415.py", line 9, in check_word
        raise LowerError(word)
    LowerError: macbook

    最初にclassで、組み込み例外のExceptionのクラスの中にLowerErrorというユーザー定義例外を作ります。構文上必要なので【何もしない】という意味のpass文を使っています。

    次に、ローカルエリアで定義したリストwordsの中に、すべて小文字の値があれば、LowerErrorを呼び出し、その値を表示する関数check_wordを作って実行しました。

    リストwordsの中には、macbookという小文字だけの値があるので、raise文によって、LowerError(word)が返されています。

    classは、まだ学習していませんが、現状では、プログラムを書く上で必要不可欠で、いろいろなものをまとめておけるものと考えておけばいいでしょう。

    また、pass文は、ルール上何かを書く必要があるけど何も実行する必要がないという場合に使うもので、空の関数や空のクラスを定義するときに使います。

    例外処理と組み合わせる

    上記のユーザー定義例外と関数の実行を例外処理のtry文と組み合わせてみましょう。

    class LowerError(Exception):
        pass
    
    def check_word():
        words = ['iPad', 'iPhone', 'macbook']
        for word in words:
            if word.islower():
                raise LowerError(word)
    
    try:
        check_word()
    except LowerError as exc:
        print("This is our fault : {}".format(exc))
    else:
        print('Done')

    出力結果

    This is our fault : macbook

    ユーザー定義例外のLowerErrorが起こったときに、This is our fault : 値(word)と表示されるtry-except文なので、リストwords中のmacbookMacbookに変えるとelse文によって、Doneが出力されてプログラムが終了します。

    コードを書かないとわからない

    酒井さんのPython講座を受講して学習しているわけですが、講座はPythonの基礎から幅広く学習できる内容です。

    Udemy講師 酒井さん プログラミング Python

    このあたりのチャプターになってくると初心者から脱却しないと理解できない内容が入ってきます。

    私はすでに2ヶ月間、Python学習をすすめてきたので、ある程度内容が理解できるようになってきましたが、今回の内容を理解するまでには、チャプターを10回以上繰り返して確認し、そのうえでユーザー定義例外やclasspass文、rase文のことを複数のサイトで調べました。

    つまり、わからないことが出てきたら自分で調べて理解するという努力をしなければ、間違いなく挫折する内容に入ってきています。

    具体的にどのような使い方をするのかはなかなかイメージができませんが、今回の内容であれば、組み込み例外が起こらないにしてもコードを書いていて、ついつい間違ってしまうところ(今回の例なら大文字にしなければいけないところを小文字にしてしまう)をチェックするために活用するんだなということがわかります。

    どうしても、たとえが短いコードになるので、そんな必要ある?と思ってしまうかもしれませんが、実際のプログラムは果てしなく長いコードなので、ユーザー定義例外を作ってチェックすることで、細かいチェックができるということですね。

    まだまだ先の長いPython学習ですが、講座においていかれないようにしたいと思います。

    それでは明日も、Good Python!