皆さんご存知Python3。Python3には、意外とexit関数にあたるものが多いです。今回は、これらを紹介して、使い分けについて話していこうと思います。
TL;DR
exit()
← 対話型インタプリタで使うべきquit()
←exit()
と同じsys.exit()
← 普通のスクリプトで使うべきos._exit()
← 子プロセスの終了に使うべきraise SystemExit
←使わないべき
使い分け
exit(code: Optional[int|Any] = None)
, quit(code: Optional[int|Any] = None)
1
どちらも_sitebuiltins.Quitter
オブジェクトで、site.main()
を実行する、もしくはPython3インタプリタを-S
オプションなしで起動することで自動的に定義されます。
公式ドキュメントには、この2つを含めた「siteモジュールによって定義される定数」について、
They are useful for the interactive interpreter shell and should not be used in programs.
https://docs.python.org/3/library/constants.html
と言及し、インタラクティブシェルでのみの使用を推奨しています。そのため、モジュールやスクリプトにてこの2つを使用することは控えたほうが良さそうです。
sys.exit(code: Optional[int|Any] = None)
1
builtin_function_or_method
オブジェクト。sys
モジュールをインポートすると使えるようになります。
SystemExit
例外(後述)を送出します。モジュールやスクリプトでは基本的にこの関数を使用して終了させます。理由としては、公式ドキュメントには
Since
https://docs.python.org/3/library/sys.htmlexit()
ultimately “only” raises an exception, it will only exit the process when called from the main thread, and the exception is not intercepted. Cleanup actions specified by finally clauses oftry
statements are honored, and it is possible to intercept the exit attempt at an outer level.
とありますが、内部では結局_sitebuiltins.Quitter
とほとんど同じ処理をしている2ので、そこまで違いはなさそうです。
os._exit(n: int)
sys.exit
と同じく、builtin_function_or_method
オブジェクト。osモジュールをインポートすると使えるようになります。
SystemExit例外の送出ではなく、C言語の_exit()
関数が直接呼び出されます。そのため、クリーンアップ処理や、標準入出力バッファのフラッシュは行われません。os.fork()
された子プロセスの終了や、緊急終了に使うべきで、通常のモジュール、スクリプト、インタラクティブシェルでは使用されるべきではありません。
引数n
は終了コードで、他とは違い必須となっています。また、intしか受け付けません。int以外の引数が渡された場合、TypeError
例外が送出されます。
raise SystemExit(code: Optional[int|Any] = None)
1
os._exit()
を除く全てのexit
関数が共通して呼び出す、「インタプリタを終了させる」という例外SystemExit
を送出されます。
SystemExit
例外は、送出されてもエラーとして扱われずに、クリーンアップ処理などを行ってからインタプリタを終了させる例外です。
確かにSystemExit
を送出するとインタプリタが終了しますが、明らかに他の選択肢よりもPythonic3な書き方ではないので控えたほうが良さそうです。
まとめ(?)
TL;DRに書いた通り、普段はsys.exit()
を使用するのが良さそうです。
ちなみに、sys.exit
や_sitebuiltins.Quitter
が送出するSystemExit
例外はBaseException
例外を継承した例外として扱えるので、
import sys
try:
sys.exit()
except SystemExit:
...
raise
みたいにすると、sys.exit()
などのSystemExit
例外を用いた終了を無視させたり、終了する前に独自のクリーンアップ処理を行わせることができます。状況に応じて、応用してみてください。
- 引数に終了コードまたはエラーコードを受け取る。終了コード(
int
)を受け取ると、そのステータスで終了する。Noneを受け取ると、1
と解釈される。int
ではないエラーコードを受け取ると、基本的にはそのオブジェクトをエラーコードとして標準エラー出力に出力し、ステータス1で異常終了する。詳しくはsysモジュールのドキュメントを参照。 [↩] [↩] [↩] - みんなだいすきstack overflowにて参考になる回答が載っています。 [↩]
- 端的に言えば、Pythonらしい、きれいで読みやすいコードのこと。 [↩]