LoginSignup
0
0

【Python】sys.exit(1)を使ってTrackback情報等を出力させずにプログラムを終了させる

Posted at

概要

例外エラーの捕捉やエラーメッセージの出力を実装していると、余計な情報は出さすにプログラムを終了させたい場合や更なるエラーが出さないようにしたいケースがあります。そんな時に、sys.exit(1)を使うと有用だったので紹介します。

サンプルコード

Pythonの組み込みモジュールであるsysexit関数を利用することで、プログラムを終了させることができます。
こちらを利用したコードが以下。

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を使用せずにデバッグ情報を確認できるようが有用でしょう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0