Pythonの例外処理!try-exceptをわかりやすく解説!

プログラミングにおいてエラーはつきものです。

Pythonではtry-exceptで「例外処理(exception)」を記述しておくことで、予期せぬエラーを未然に防ぐことができます。

この記事では

  • エラーと例外の違いについて
  • try-exceptの基本的な使用方法

といった基本的な内容から

  • raiseとpassについて
  • elseとfinallyについて
  • 例外が複数ある場合

などといったより応用的な内容に関しても、やさしく解説していきたいと思います。

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

エラーと例外の違いについて

プログラムを書いていると、エラーは付き物です

Pythonを使っていると様々なエラーメッセージを目にすることがありますが、これらは主に

  • 構文エラー
  • 例外

の二つのカテゴリに分けることが出来ます。

構文エラーとは

構文エラーとは文法的な間違いによって発生するエラーのことです。英語ではSyntax Errorとも言い、Pythonにおける文法ルールなどに従わないコードを実行したときに発生するものです。

例えば、出力させたい文字列を括弧の中に入れないでprint関数を呼び出してしまうと以下のようなエラーが発生します。

  File "<stdin>", line 1
    print "hello world"
                      ^
SyntaxError: Missing parentheses in call to 'print'

括弧をつけずにprint関数を呼び出すことができたのはPython2系であり、3系ではこのようなエラーが発生することが確認できました。

構文エラーが発生するとプログラムは動作しないので、これらの解消に努力しなければなりません。

例外とは

文法的に正しいコードを書いても、実行時にエラーが発生することがあります。

これが「例外」というものです。英語ではExceptionといい、よく出てくるキーワードなので覚えておきましょう。

例えば、文字列の割り算を以下のように行ってみましょう。

words = "Hello"
print (words/2)

上記のコードを実行してみると、以下のようなエラーが発生します。

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for /: 'str' and 'int'

上のコードでは、TypeErrorが発生しました。TypeErrorとは直訳すると型エラーであり、今回のように計算に使える型ではないstringを使用した際などに発生します。

また、これ以外にも様々な例外があります。

  • ZeroDivisionError

例:ZeroDivisionError: division by zero
1/0のようにゼロで割ってしまったときに起きるエラー

  • NameError

例:NameError: name 'hoge' is not defined
定義していない変数を使ったときに起きるエラー

  • AttributeError

例:AttributeError: type object ‘list’ has no attribute 'fuga'
存在しない属性にアクセスしようとしたときに起きるエラー

などが代表的です。

try-exceptの使い方

構文エラーと例外の違いについて理解したところで、例外が発生したときにはどのように対処すればよいのか解説していきたいと思います。

基本的には try-except文を使用し「例外処理」を行います。try-except構文は以下の通りです。

try: 
    例外が発生するかもしれないが、実行したい処理。
except エラー名:
    例外発生時に行う処理

まずは、tryの中に指定された処理が実行されます。例外が発生しなければ、except文はスキップされます。

しかし、try実行中にexceptキーワードの後に指定したエラー名と一致する例外が発生すると、except文が実行され、それ以降に記述された処理も実行されます。

このように「except」ブロックで例外を捉えて処理をすることで、エラー発生箇所で処理が停止することはありません。

では実際にtry-except文を使用してみましょう。以下のサンプルコードをご覧ください。

x = 1
y = 0
 
try:
    z = x / y
except ZeroDivisionError:
    print('You can not do this operation!')

print('Hello world!')

出力結果は以下の通りです。

You can not do this operation!
Hello world!

上のコードでは、try-except文を使用し、ゼロで割ったときに「You can not do this operation!」という文字列を出力させました。

そして、try‐exceptブロック外に記述されたHello World!という文字列の出力も、正常に行われました。

なお、try-except文を使用しないと以下のような出力結果になります。[try-except文を使わない場合のコード]

x = 1
y = 0
z = x / y # 今までtryブロックの中にあったコード
print('Hello world!')

Output

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

ご覧いただけるように、ZeroDivisionErrorが表示されてしまい、処理がストップしてしまいます。

その為、Hello World!という文字列は表示されませんでした。

例外が発生した後の処理とは

「except」ブロックで実行する処理は、様々なパターンがあるのでそれぞれご紹介していきたいと思います。

具体的には

  • 故意に例外を起こす場合はraise句
  • 例外発生後に何も処理を行わない場合はpass句
  • 例外が発生しなかった場合にのみ処理を行う場合はelse句
  • 例外の発生に関わらず必ず処理を行う場合はfinally句

になります。

raiseとpassについて

故意に例外を起こす場合は「raise」句を使用します。

以下のサンプルコードをご覧ください。

try:
    raise ZeroDivisionError
except:
    print('故意にエラーを発生')

出力結果は以下の通りです。

故意にエラーを発生

上のコードでは「try」ブロック内で「raise」句を使用して故意に例外を発生させ、「except」ブロックで例外を捉え「故意にエラーを発生」と表示させています。

例外発生後に何も処理を行わない場合は「pass」句を使用します。以下のサンプルコードをご覧ください。

x = 1
y = 0

try:
    z = x / y
except:
    pass

上のコードでは、「pass」句を使うことで、「z = x / y」というゼロでの割り算によるエラー発生後は何も起こりません。

elseとfinallyについて

例外が発生しなかった場合に行う処理を明記する場合は「else」ブロックを使用します。例外の発生に関わらず必ず処理を行いたい場合は「finally」ブロックを使用します。

これらの使用方法については、二つとも同じサンプルコードをご覧ください。

x = 1
y = 0
 
try:
    z = x / y
except:
    print('例外発生!ゼロで割ることはできません')
else:
    print('例外は発生しませんでした。')
finally:
    print('実行が終了しました')

出力結果は以下の通りです。

例外発生!ゼロで割ることはできません
実行が終了しました

上のコードでは、ゼロでの割り算を行っています。ゼロで割り算を行った場合、例外が発生するのでexcept文が発動します。

else句はエラーが発生したため発動せず、「finally」ブロックはエラーの発生に関わらず処理が行われます。

例外が複数ある場合

これまでは一つの例外が発生する場合について説明してきました。例外が複数ある場合に例外の種類に応じて処理を分ける方法があるので、ご紹介していきたいと思います。

以下のサンプルコードをご覧ください。

x = 1
y = 0
 
try:
    z = x / y
    f = open('text.txt')
except ZeroDivisionError:
    print("Zero division")
except FileNotFoundError:
    print("File not found")
finally:
    print('処理が終了しました')

出力結果は以下の通りです。

Zero division
処理が終了しました

上のサンプルコードでは「z = x / y」というゼロでの割り算と「f = open('text.txt')」という存在しないファイルを開く処理を行おうとしています。

「except」ブロックを複数記述することで、複数の例外処理を行うことができます。

注意したい点は、先に記述した処理が実行され例外が発生していますが、後に記述した処理は実行されていないというところです。

記述の順番により実行される処理と実行されない処理があるので、記述する順番には注意しましょう。

まとめ

この記事では、Pythonにおける基本的な例外処理を解説しました。

プログラミングにおいてエラーの発生はなかなか免れないものですが、例外処理を使うことでエラーが発生しても実行が中止することなくそれ以降の処理も行われるので、便利です。

皆さんもこの記事を通して、例外処理をどんどんマスターしていってくださいね。

なお、今Pythonを学習している方は以下の記事もどうぞ。

はじめてPythonを使う方でもわかりやすいように、Pythonでできることやその学習法などを中心にまとめています。

復習にも使えると思いますので、ぜひ一度ご覧になってみてくださいね。

Python 入門完全攻略ガイド

「プログラミング、右も左もわからない…」という方にオススメ

当プログラミングスクール「侍エンジニア塾」では、これまで6000人以上のエンジニアを輩出してきました。

その経験を通してプログラミング学習に成功する人は、「目的目標が明確でそれに合わせた学習プランがあること」「常に相談できる人がそばにいること」「自己解決能力が身につくこと」この3つが根付いている傾向を発見しました。

侍エンジニア塾は上記3つの成功ポイントを満たすようなサービス設計に磨きをかけております。

cta_under_bnr

「自分のスタイルや目的に合わせて学習を進めたいな」とお考えの方は、ぜひチェックしてみてください。

書いた人

Kotono

イタリア在住15年目の22歳です。イタリアの大学で情報科学&応用数学を学んでいます。主にJavaScriptやPythonについての記事を書いたりしています。

おすすめコンテンツ

まずはここから!初心者でも1から学べるプログラミング入門カリキュラム

転職成功で受講料0円!あなたもプログラミングを学んでエンジニアデビュー