概要
例外エラーの捕捉やエラーメッセージの出力を実装していると、余計な情報は出さすにプログラムを終了させたい場合や更なるエラーが出さないようにしたいケースがあります。そんな時に、sys.exit(1)
を使うと有用だったので紹介します。
サンプルコード
Pythonの組み込みモジュールであるsys
のexit
関数を利用することで、プログラムを終了させることができます。
こちらを利用したコードが以下。
import sys
def divide(x, y):
if y == 0:
print("エラー: 0で除算することはできません。")
sys.exit(1)
return x / y
print(divide(10, 0))
# エラー: 0で除算することはできません。
もし、sys.exit(1)
がない状態だとどうなるでしょうか?
import sys
def divide(x, y):
if y == 0:
print("エラー: 0で除算することはできません。")
# sys.exit(1)
return x / y
print(divide(10, 0))
# エラー: 0で除算することはできません。
# Traceback (most recent call last):
# File "/Users/xxx/xxx/xxxx/test-sys-exit.py", line 10, in <module>
# print(divide(10, 0))
# File "/Users/xxx/xxx/xxxx/test-sys-exit.py", line 8, in divide
# return x / y
# ZeroDivisionError: division by zero
上記の通り、Traceback情報(Pythonのデバッグ情報)などがずらずらと出力されます。
終了ステータスコードとSystemExit
例外
指定したsys.exit(1)
の引数1
は終了ステータスコードと呼び、プログラムをエラー状態で終了させることを意味しています。
整数を指定した場合、シェル等は 0 は "正常終了"、0 以外の整数を "異常終了" として扱います。
sys.exit([arg])
の公式ドキュメントはこちら。
また。sys.exit()
は、SystemExit
例外を発生させ、これが捕捉されない場合は、Pythonインタープリタを終了する、という点も大事です。
この例外は sys.exit() 関数から送出されます。Exception をキャッチするコードに誤ってキャッチされないように、Exception ではなく BaseException を継承しています。これにより例外は上の階層に適切に伝わり、インタープリタを終了させます。この例外が処理されなかった場合はスタックのトレースバックを表示せずに Python インタープリタは終了します。
https://docs.python.org/ja/3.7/library/exceptions.html#SystemExit
つまり、以下のように実装することも可能ではあります。
本来プログラムを終了させるためのものなので、あまり使われるようなケースはないと思いますが。
import sys
def divide(x, y):
try:
if y == 0:
sys.exit("エラー: 0で除算することはできません。")
except SystemExit as e:
print("SystemExit例外が捕捉されました:", e)
return "エラー"
return x / y
print(divide(10, 0))
# SystemExit例外が捕捉されました: エラー: 0で除算することはできません。
# エラー
上記の場合、SystemExit
例外がtry/except
ブロックで捕捉され、エラーメッセージが表示されますので、プログラムは終了せずに続行します。
引数にエラーメッセージ指定も可能
ちなみに、sys.exit()
の引数にエラーメッセージを直接指定してあげることも可能です。
import sys
def divide(x, y):
if y == 0:
sys.exit("エラー: 0で除算することはできません。")
return x / y
print(divide(10, 0))
# エラー: 0で除算することはできません。
とはいえエラーの特定をしたい場合はTraceback情報のエラーメッセージやスタックトレースが大事になるので、その際はもちろんsys.exit
を使用せずにデバッグ情報を確認できるようが有用でしょう。