Pythonスクリプトを終了する方法


1079

私はdie()、スクリプトを早期に終了するPHP のコマンドを認識しています。

Pythonでこれを行うにはどうすればよいですか?

回答:


1418
import sys
sys.exit()

sysモジュールのドキュメントの詳細:

sys.exit([arg])

Pythonを終了します。これは、SystemExit例外を発生させることで実装される ため、tryステートメントのfinally節で指定されたクリーンアップアクションが尊重され、外部レベルでの終了試行をインターセプトすることが可能です。

オプションの引数argは、終了ステータスを与える整数(デフォルトはゼロ)または別のタイプのオブジェクトです。整数の場合、ゼロは「正常終了」と見なされ、ゼロ以外の値はシェルなどによって「異常終了」と見なされます。ほとんどのシステムでは、0〜127の範囲にある必要があり、それ以外の場合は未定義の結果が生成されます。一部のシステムには、特定の意味を特定の終了コードに割り当てるための規則がありますが、これらは一般的に開発が不十分です。Unixプログラムは通常、コマンドライン構文エラーに2を使用し、その他すべての種類のエラーに1を使用します。別のタイプのオブジェクトが渡される場合、Noneはゼロを渡すことと同等であり、他のオブジェクトはすべて出力さstderrれ、終了コード1になります。特に、 sys.exit("some error message") エラーが発生したときにプログラムを終了する簡単な方法です。

のでexit()、最終的に「唯一の」例外を発生させ、メインスレッドから呼び出されると、例外が傍受されていない場合、それが唯一のプロセスを終了します。

これは終了する「素敵な」方法であることに注意してください。以下の@ glyphtwistedmatrixは、「強制終了」が必要な場合に使用できることを指摘していますがos._exit(*errorcode*)、ある程度はOS固有である可能性が高く(たとえば、Windowsでエラーコードを取得しない可能性があります)、間違いなくフレンドリーではありません。プロセスが終了する前にインタープリターがクリーンアップを行うことはできません。


9
sys.exit()バックグラウンドスレッドで発生した場合、おそらく機能しません(プロセスを強制終了せず、スレッドを強制終了します)。

@ cesium62:はい、sys.exit()上昇しSystemExit、現在のスレッドで例外を。
ドミトリーTrofimov

13
例外を発生させずにスクリプトを終了する方法はありますか?Popenへの標準出力のパイピングにprintを使用して、スクリプトから関連するフラグを既に渡しています。そのため、この場合の例外は、解決している以上の問題を引き起こしています。
エリオット

4
:私はこの方法を使用する場合、なぜ、私は次の警告を取得しますUserWarning: To exit: use 'exit', 'quit', or Ctrl-D. warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
ビル・

1
詳細が必要です。多分それはそれ自体の質問に値するのに値しますか?
pjz

349

Pythonスクリプトを早期に終了する簡単な方法は、組み込みquit()関数を使用することです。ライブラリをインポートする必要はなく、効率的で簡単です。

例:

#do stuff
if this == that:
  quit()

86
また、sys.exit()はすべてのPythonスクリプトを終了しますが、quit()はそれを生成したスクリプトのみを終了します。
VishalDevgire 2013

4
このコマンドがpython 2とpython 3で異なる動作をするかどうか知っていますか?
David C.

1
これがインタプリタ全体を終了するのか、それともスクリプトの実行を停止するのかを誰かが知っていますか?具体的には、Spyderで実行されているスクリプトの場合、Pythonインタープリターは対話型のままですか、それとも強制終了されますか?スクリプトの続行を止めるようにしてください。ただし、インタプリタの対話性はそのままにしておきます。
Demis

3
私にとっては、「終了」は定義されていません。私はpython 3を使用しています
Vincenzooo

4
私はpython 3.7で、quit()はインタープリターを停止し、スクリプトを閉じます。
RockAndRoleCoder

120

別の方法は:

raise SystemExit

36
@Alessa:よりエレガントに見えますが、お勧めできません:望ましい(そして上書き可能な)sys.exitラッパーの代わりに組み込みの例外を直接発生させています
MestreLion

1
これは私にとって完璧な方法です。実行中のスクリプトを終了するだけでIDLEは終了しません
rml

78

簡単に使用することもできますexit()

ことを覚えておいてくださいsys.exit()exit()quit()、とos._exit(0) 殺す Pythonインタプリタを。したがって、によって別のスクリプトから呼び出されたスクリプトに出現すると、execfile()両方のスクリプトの実行が停止します。

これを回避するには、「execfileで呼び出されるスクリプトの実行を停止する」を参照してください。


67

sys.exit他のコードよりも「友好的」であるため、通常は優先する必要がありますが、実際には例外が発生するだけです。

あなたがすぐにプロセスを終了する必要があると確信していて、あなたがキャッチするいくつかの例外ハンドラの中にいるかもしれない場合 SystemExitある場合は、別の関数がos._exitあります--Cレベルですぐに終了し、通常のティアダウンは実行されません通訳の; たとえば、「atexit」モジュールに登録されたフックは実行されません。


43

マルチスレッドのアプリを作成しているときにraise SystemExitsys.exit()どちらも実行中のスレッドのみを強制終了することがわかりました。一方、os._exit()プロセス全体を終了します。これについては、「Pythonのスレッド内で呼び出されたときにsys.exit()が終了しないのはなぜですか?」で説明しました。

以下の例には2つのスレッドがあります。ケニーとカートマン。カートマンは永遠に生きるはずですが、ケニーは再帰的に呼ばれ、3秒後に死ぬはずです。(再帰呼び出しは最良の方法ではありませんが、他の理由がありました)

ケニーが亡くなったときにカートマンも死にたい場合、ケニーはを廃止する必要がありos._exitます。そうでなければ、ケニーだけが死に、カートマンは永遠に生きます。

import threading
import time
import sys
import os

def kenny(num=0):
    if num > 3:
        # print("Kenny dies now...")
        # raise SystemExit #Kenny will die, but Cartman will live forever
        # sys.exit(1) #Same as above

        print("Kenny dies and also kills Cartman!")
        os._exit(1)
    while True:
        print("Kenny lives: {0}".format(num))
        time.sleep(1)
        num += 1
        kenny(num)

def cartman():
    i = 0
    while True:
        print("Cartman lives: {0}".format(i))
        i += 1
        time.sleep(1)

if __name__ == '__main__':
    daemon_kenny = threading.Thread(name='kenny', target=kenny)
    daemon_cartman = threading.Thread(name='cartman', target=cartman)
    daemon_kenny.setDaemon(True)
    daemon_cartman.setDaemon(True)

    daemon_kenny.start()
    daemon_cartman.start()
    daemon_kenny.join()
    daemon_cartman.join()

1
これは、不愉快に延期されたコールバックを処理する唯一の方法のようです!(つまり、マルチスレッドメソッド)
not2qubit 2018年

1
よくやった。他の答えはどれも直接複数のスレッドに対応せず、他のスクリプトを生成するスクリプトのみです。
匿名

33
from sys import exit
exit()

パラメータとして、OSに返される終了コードを渡すことができます。デフォルトは0です。


3
私の場合、exitをインポートする必要すらありませんでした。
コスタノス2013年

5
上記のコメントの子孫のためだけに- exit()sys.exit()同じことではありません。exit()スクリプトで組み込みを使用しないでください。これはインタラクティブシェルのヘルパーにすぎません-使用sys.exit()
daveruinseverything

18

私は完全に初心者ですが、確かにこれはよりクリーンでより管理されています

def main():
    try:
        Answer = 1/0
        print  Answer
    except:
        print 'Program terminated'
        return
    print 'You wont see this'

if __name__ == '__main__': 
    main()

...

プログラムが終了しました

より

import sys
def main():
    try:
        Answer = 1/0
        print  Answer
    except:
        print 'Program terminated'
        sys.exit()
    print 'You wont see this'

if __name__ == '__main__': 
    main()

...

プログラムがトレースバックを終了しました(最新の呼び出しが最後):main()のファイル "Z:\ Directory \ testdieprogram.py"、12行目メインのsys.exit(のファイル "Z:\ Directory \ testdieprogram.py"、8行目)SystemExit

編集する

ポイントは、「やめた!!!」ではなく、プログラムがスムーズかつ平和に終了することです


20
1つの問題は、ネストされた関数を使用していて、単に終了したい場合、フラグを最上位の関数まで送信するか、次のレベルに戻るかです。
horta 2015年

11
を使用returnしてスクリプトを終了できると提案しようとしている場合、これはまったくナンセンスです。すべてのreturn値および関数呼び出しへの制御の流れを返してやっています。そこでは、呼び出した関数の呼び出し直後に実行を継続しreturnます。もちろん、return例のようにスクリプトの最後のステートメントがである場合、スクリプトは呼び出された直後に終了します。
David FerenczyRogožan2017年

1
このアプローチについては、強い議論があります。(1)途中からの「終了」は間違いなく「後藤」であり、したがって自然な嫌悪です。(2)ライブラリでの「exit」は間違いなく悪い習慣です(そして何でもライブラリになる可能性があります)。ライブラリが「回復不能」と見なすものは通常、呼び出し側にとって問題ないからです。(注:出口に例外を使用することは、C / C ++ / Java開発者が常に不適切に呼び出すpythonの実用的な回避策ですexit-したがって、Pythonプログラマーはこのコードの悪臭にそれほど気づかない場合があります); そして最後に、(3)マルチスレッドコード(これまでのpythonistaはこれまで無視してきました)。
マイケル

8

Python 3.5では、スクリプトを停止してユーザーにエラーメッセージを出力するために組み込まれているもの以外のモジュール(sys、Biopyなど)を使用せずに、同様のコードを組み込もうとしました。これが私の例です:

## My example:
if "ATG" in my_DNA: 
    ## <Do something & proceed...>
else: 
    print("Start codon is missing! Check your DNA sequence!")
    exit() ## as most folks said above

後で、エラーをスローする方が簡潔であることがわかりました。

## My example revised:
if "ATG" in my_DNA: 
    ## <Do something & proceed...>
else: 
    raise ValueError("Start codon is missing! Check your DNA sequence!")

アプリケーションで処理できるエラーについては、例外を発生させる方がよいことに完全に同意します。しかし、問題はPythonスクリプトを終了する方法だったので、これは実際には(新しい)答えではありません。
wovano

-1

私の2セント。

Python 3.8.1、Windows 10、64ビット。

sys.exit() 私には直接働きません。

次のループがいくつかあります。

まず、ブール変数を宣言しますimmediateExit。これをと呼びます。

したがって、プログラムコードの冒頭で、次のように記述します。

immediateExit = False

次に、最も内側の(ネストされた)ループ例外から始めて、次のように記述します。

            immediateExit = True
            sys.exit('CSV file corrupted 0.')

次に、すぐ外側のループに進み、他のコードによって実行される前に、次のように記述します。

    if immediateExit:
        sys.exit('CSV file corrupted 1.')

複雑さによっては、上記の記述をセクション以外でも繰り返す必要がある場合があります。

    if immediateExit:
        sys.exit('CSV file corrupted 1.5.')

カスタムメッセージは、私の個人的なデバッグ用でもあります。数字は同じ目的のためです。つまり、スクリプトが実際に終了する場所を確認するためです。

'CSV file corrupted 1.5.'

私の特定のケースでは、ソフトウェアが破損していることをソフトウェアが検出した場合、ソフトウェアに触れさせたくないCSVファイルを処理しています。したがって、私にとって、破損の可能性を検出した直後にPythonスクリプト全体を終了することが非常に重要です。

そして、私が管理するすべてのループからの段階的なsys.exit-ingに従います。

完全なコード:(内部タスクの所有権コードであるため、いくつかの変更が必要でした):

immediateExit = False
start_date = '1994.01.01'
end_date = '1994.01.04'
resumedDate = end_date


end_date_in_working_days = False
while not end_date_in_working_days:
    try:
        end_day_position = working_days.index(end_date)

        end_date_in_working_days = True
    except ValueError: # try statement from end_date in workdays check
        print(current_date_and_time())
        end_date = input('>> {} is not in the list of working days. Change the date (YYYY.MM.DD): '.format(end_date))
        print('New end date: ', end_date, '\n')
        continue


    csv_filename = 'test.csv'
    csv_headers = 'date,rate,brand\n' # not real headers, this is just for example
    try:
        with open(csv_filename, 'r') as file:
            print('***\nOld file {} found. Resuming the file by re-processing the last date lines.\nThey shall be deleted and re-processed.\n***\n'.format(csv_filename))
            last_line = file.readlines()[-1]
            start_date = last_line.split(',')[0] # assigning the start date to be the last like date.
            resumedDate = start_date

            if last_line == csv_headers:
                pass
            elif start_date not in working_days:
                print('***\n\n{} file might be corrupted. Erase or edit the file to continue.\n***'.format(csv_filename))
                immediateExit = True
                sys.exit('CSV file corrupted 0.')
            else:
                start_date = last_line.split(',')[0] # assigning the start date to be the last like date.
                print('\nLast date:', start_date)
                file.seek(0) # setting the cursor at the beginnning of the file
                lines = file.readlines() # reading the file contents into a list
                count = 0 # nr. of lines with last date
                for line in lines: #cycling through the lines of the file
                    if line.split(',')[0] == start_date: # cycle for counting the lines with last date in it.
                        count = count + 1
        if immediateExit:
            sys.exit('CSV file corrupted 1.')
        for iter in range(count): # removing the lines with last date
            lines.pop()
        print('\n{} lines removed from date: {} in {} file'.format(count, start_date, csv_filename))



        if immediateExit:
            sys.exit('CSV file corrupted 1.2.')
        with open(csv_filename, 'w') as file:
            print('\nFile', csv_filename, 'open for writing')
            file.writelines(lines)

            print('\nRemoving', count, 'lines from', csv_filename)

        fileExists = True

    except:
        if immediateExit:
            sys.exit('CSV file corrupted 1.5.')
        with open(csv_filename, 'w') as file:
            file.write(csv_headers)
            fileExists = False
    if immediateExit:
        sys.exit('CSV file corrupted 2.')

1
あなたの貢献に感謝しますが、私にとってこの答えは意味がありません。完全な例の代わりにコードのスニペットをいくつか投稿するだけなので、あなたが何を意味するのか理解するのは難しいです。ここに投稿したコード行だけで、スクリプトはすぐに終了します。他の回答ですでに言及されているSystemExit例外をキャッチするtry-catchブロックがあると推測できます。アプリケーションを完全に終了する方法の完全な動作例(つまり、必要なシャットダウンアクションを実行すること)で回答を書き換える場合、投稿が役立つと思います。
wovano

ご意見ありがとうございます。次に、exitステートメントに関するコードの一部を追加しました。
マシュー

さて、これはもう少しコンテキストを与えます:)今私は今あなたの解決策は実際には非常に悪いプログラミングパターンの回避策だと思います まず、except:例外タイプなしで使用してはいけません。を使用するだけの場合except Exception:(または可能であればさらに詳細な例外タイプ)、sys.exit()意図したとおりに機能し、この回避策は必要ありません。
wovano

次に、1つのメソッドで、またはおそらくグローバルファイルスコープでさえ、かなりの数のことを実行しようとしているように見えます。たとえば、(1)入力ファイルの読み込み、(2)プロセスデータ、(3)出力ファイルの書き込みなど、コードをより小さな部分(関数)に分割すると役立ちます。次に、ステップ1が失敗した場合は、ステップ2と3をスキップします。ロードステップ中の任意の場所で例外を発生させ、1か所で例外を処理できます。を使用することsys.exit()は、実際には重大なエラーに対する一種の最後の手段です。ちょうど私の2セント:)
wovano

一般に、Pythonにはグローバルな終了/停止機能はありません。このようにする必要があります。CSVファイルは私にとって非常に重要なので、手段が醜く見えても、可能な限り保護します。私のスタイルを改善するために、The Hichhicker's Guide to Pythonを読んでいます。
マシュー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.