Pythonでは対話環境を終了するexit関数、sysモジュールが提供するexit関数、osモジュールが提供する_exit関数という3つのexit関数がある。これらの違いをまとめる。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
関数 | 説明 |
---|---|
exit関数 | Pythonの対話シェルで使用可能。標準入力をクローズしてSystemExit例外を発生させ、その結果として対話シェルが終了する |
sys.exit関数 | sysモジュールが提供する関数。SystemExit例外を発生させる。これはプログラムを終了させようとしているのだとPython処理系に伝えるものであり、その結果としてプログラムが終了する。SystemExit例外を捕捉して何らかのクリーンアップ処理を行うことが可能 |
os._exit関数 | 引数に指定した終了ステータスでプログラムを即時に終了する。何らかのクリーンアップ処理を行うことはない |
3つのexit関数 |
Pythonにはプログラムを任意の箇所で終了するための「exit関数」といえるものが3種類ある。
以下では、これらについて簡単にまとめていく。
REPL(Pythonの対話シェル)では、対話環境を終了するのにexit関数を呼び出す。
その実体はPythonに組み込みの_sitebuiltins.Quitterクラスのオブジェクトである。このオブジェクトを関数のように呼び出すと、対話環境が終了する。内部的には、以下に示すように標準入力をクローズした後に、SystemExit例外を発生させるようになっている。
class Quitter(object):
def __init__(self, name, eof):
self.name = name
self.eof = eof
def __repr__(self):
return 'Use %s() or %s to exit' % (self.name, self.eof)
def __call__(self, code=None):
try:
sys.stdin.close()
except:
pass
raise SystemExit(code)
sys.exit関数はSystemExit例外を発生させ、Python処理系にプログラムを終了しようとしていることを伝える。sys.exit関数には終了ステータスを指定できる。省略した場合には0が指定されたものとして扱われる。プログラムが終了する際には、正常に終了するのであれば終了ステータスは0に、そうでなければ0以外の値とする。
Python処理系はSystemExit例外を受け取ると、クリーンアップ処理(atexitモジュールを使って登録された終了ハンドラーなど)を実行した後にプログラムを終了させる。
以下に例を示す。
import atexit
import sys
def cleanup():
print('cleanup')
atexit.register(cleanup)
print('call sys.exit func')
sys.exit()
print('after calling sys.exit func')
この例ではクリーンアップ処理を行うcleanup関数を定義して、それをatexit.register関数で登録し、その後、sys.exit関数を呼び出している。実行すると次のようになる。
このように、sys.exit関数を呼び出すと、atexitモジュールで登録されたクリーンアップ処理が実行されてからプログラムが終了する(sys.exit関数を呼び出した後のコードが実行されていない点にも注目されたい)。
また、この関数はあくまでもSystemExit例外を発生させるものなので、これを捕捉してそれを処理することも可能だ。以下に例を示す。
import sys
try:
sys.exit()
except SystemExit:
print('in except')
finally:
print('in finally')
実行結果を以下に示す。
SystemExit例外を捕捉するexcept節と最後のfinally節が実行されていることが分かるはずだ。
このように、sys.exit関数はPythonプログラムの任意の位置で、クリーンアップ処理を伴ってプログラムを終了させる際に使用する。
一方、os._exit関数は引数に指定した終了ステータス(省略不可)でプログラムを終了させる。sys.exit関数とは異なり、クリーンアップ処理は行われない。
以下に例を示す。
import atexit
import os
def cleanup():
print('cleanup')
atexit.register(cleanup)
print('call os._exit func')
os._exit(0)
print('after calling os._exit func')
これは先ほどのatexitモジュールでクリーンアップ処理を登録するコードを、sys.exit関数の代わりにos._exit関数を呼び出すように改変したものだ。実行結果を以下に示す。
画像に示した通り、クリーンアップ処理が行われることなく、プログラムが終了している。
コードの任意の位置でプログラムを終了するのであれば、一般的にはsys.exit関数を使うのがよいだろう。
Copyright© Digital Advantage Corp. All Rights Reserved.