※この記事はUdon Advent Calendar 2024 - Adventarの23日目の記事です。
はじめに
こんにちは。Udonです。このアドベントカレンダーも終盤ですね。
今日はPythonのtry
構文についてまとめてみたいと思います。最近Pythonを書いているときに、参考にしている記事でよくこの構文が使われていました。なので一回まとめ、しっかりと理解しておきたいと思います。
try
構文とは
プログラミングをしていると、エラーが発生することがあります。競技プログラミングみたいに短時間だけ動作するプログラムならいいですが、システムとして動作しているときにエラーが発生してしまうと、システムが停止して再起動を強いられてしまうことがあります。致命的な例外だったら改善の余地となるのですが、データの型を間違えたとか、ケアレスミスでエラーが発生することもあります。そういうエラーでシステムがいちいち停止していると、とても不便です。
そんな時に役に立つのがtry
構文です。try
構文を使うと、エラーが発生してもプログラムが停止することなく、エラーをキャッチして、プログラムを停止させずに処理を続行することができます。
主に例外処理(プログラム言語が想定していない処理)が発生する可能性がある部分に使う構文です。
使い方
try
構文は以下のように書きます。
def calc(a, b):
try:
return a / b
except ZeroDivisionError:
return "0で割ることはできません"
これは0除算を防ぐ機能を実装したものです。b=0
の場合、通常はエラーが発生してプログラムが停止しますが、try
構文を使うことでエラーをキャッチして、エラーメッセージを返すようになります。
また、Pythonは型が動的に変わるため、型エラーが発生することもあります。その場合もtry
構文を使ってエラーをキャッチすることができます。
def calc(a, b):
try:
return a / b
except ZeroDivisionError:
return "0で割ることはできません"
except TypeError:
return "型が違います"
これはa
やb
に数値ではなく文字列やリストなどが入っていた場合に発生するエラーをキャッチしています。except
を追加することにより、複数のエラーをキャッチすることができます。
except
について詳しく
エラーの種類
さっきから書いていますが、except
の後にはエラーの種類を指定することができます。
まず、ZeroDivisionError
は0除算をしたときに発生するエラーです。TypeError
は型エラーが発生したときに発生するエラーです。他にも、ValueError
やIndexError
など、様々なエラーがあります。前者は値が不正な場合に発生するエラーで、後者はインデックスが不正な場合(範囲外参照など)に発生するエラーです。
また、except
の後にエラーの種類を指定しない場合、全てのエラーをキャッチすることができます。
def calc(a, b):
try:
return a / b
except:
return "エラーが発生しました"
これだと、0除算をしたときや型エラーを起こしたときに同じエラーメッセージを返すようになります。全ての例外をキャッチできますが、エラーの種類が分からないので、デバッグが難しくなります。
as
を使ってエラーの内容を取得する
as
を使ってエラーの内容を取得することができます。
def calc(a, b):
try:
return a / b
except Exception as e:
return e
こうすると、e
にエラーの内容が格納されます。これを返せば、エラーメッセージを取得することができます。
print(calc(10, 2)) #5.0
print(calc([], 2)) #unsupported operand type(s) for /: 'list' and 'int'
print(calc(10, 0)) #division by zero
エラーは英語ですが、しっかりと内容を把握することができます。逆に、英語が苦手な人には不向きかもしれません。そういう時は、エラーの内容を日本語に翻訳するライブラリを使ったり、各エラーに対して日本語のエラーメッセージを返すようにするといいかもしれません。
その他指定できるもの
try
構文には他にも指定できるものがあります。
else
else
を使うことで、エラーが発生しなかった場合に実行する処理を指定することができます。これを使うことでエラーが発生しなかった場合のみに実行したい処理を指定することができます。
def calc(a, b):
try:
return a / b
except ZeroDivisionError:
return "0で割ることはできません"
else:
return "計算が正常に終了しました"
finally
finally
を使うことで、エラーが発生してもしなくても実行する処理を指定することができます。
def calc(a, b):
try:
return a / b
except ZeroDivisionError:
return "0で割ることはできません"
finally:
print("計算が終了しました")
この場合、エラーが発生してもしなくても、"計算が終了しました"
が表示されます。try
内に書いても良い気がしますが、try
内ではどうやらエラーが発生した場所から下の処理は実行されないようです。
def calc(a, b):
try:
c= a / b
print("計算終了")
return c
except Exception as e:
return f"エラーが発生しました: {e}"
print(calc(10, 0)) #エラーが発生しました: division by zero
この場合、計算終了
は表示されません。finally
を使うことで、エラーが発生してもしなくても実行する処理を指定することができます。
def calc(a, b):
try:
c= a / b
return c
except Exception as e:
return f"エラーが発生しました: {e}"
finally:
print("計算終了")
print(calc(10, 0))
#エラーが発生しました: division by zero
#計算終了
応用事例
ファイルの読み込み
ファイルの読み込み時にエラーが発生することがあります。その場合、try
構文を使ってエラーをキャッチすることができます。
try:
with open("sample.txt", "r") as f:
print(f.read())
except FileNotFoundError:
print("ファイルが見つかりません")
ファイルを作り忘れた場合などにはFileNotFoundError
が発生します。これをキャッチしてエラーメッセージを表示します。
ネットワーク通信
ネットワーク通信時にエラーが発生することがあります。その場合もtry
構文を使ってエラーをキャッチすることができます。
メール送信
メール送信時にエラーが発生することがあります。その場合もtry
構文を使ってエラーをキャッチすることができます。
例えば、サーバに接続できなかったり(認証エラー)、メールアドレスが間違っていたり(メールアドレスエラー)、メールの内容が不正だったり(メール内容エラー)することがあります。これらのエラーをキャッチしてエラーメッセージを表示することができます。
まとめ
以上のように、try
構文を使うことでエラーをキャッチして、プログラムを停止させずに処理を続行することができます。
これによって、システムを停止させずともエラーの発生とその内容を把握し、対処を並行して進めることができます。結果、保守性や安定性が向上するわけです。
エラーが発生する可能性がある部分には、try
構文を使ってエラーをキャッチすると良いと思います。
今回の記事は以上です。また明日の記事でお会いしましょう。
参考文献
pythonのtry構文について調べてみた #Python - Qiita