파이썬 스크립트를 종료하는 방법


1076

die()스크립트를 일찍 종료하는 PHP 의 명령을 알고 있습니다.

파이썬에서 어떻게 할 수 있습니까?

답변:


1416
import sys
sys.exit()

sys모듈 문서의 세부 사항 :

sys.exit([arg])

파이썬에서 빠져 나옵니다. 이는 SystemExit예외 를 발생시켜 구현 되므로 finally try명령문 절에 지정된 정리 조치 가 적용되며 외부 레벨에서 종료 시도를 가로 챌 수 있습니다.

선택적 인수 arg 는 종료 상태 (기본값은 0)를 나타내는 정수 또는 다른 유형의 객체 일 수 있습니다. 정수이면 0은 "성공적인 종료"로 간주되고 0이 아닌 값은 쉘 등에 의해 "비정상 종료"로 간주됩니다. 대부분의 시스템은 0-127 범위에 있어야하며 그렇지 않으면 정의되지 않은 결과를 생성합니다. 일부 시스템에는 특정 종료 코드에 특정 의미를 지정하기위한 규칙이 있지만 일반적으로 저개발 상태입니다. 유닉스 프로그램은 일반적으로 명령 줄 구문 오류에 2를 사용하고 다른 모든 종류의 오류에 1을 사용합니다. 다른 유형의 객체가 전달되면 None은 0을 전달하는 것과 같고 다른 객체는 인쇄되어 stderr종료 코드 1이됩니다. sys.exit("some error message") 오류가 발생했을 때 프로그램을 종료하는 빠른 방법입니다.

때문에 exit()궁극적으로 "전용"예외가 발생 메인 쓰레드에서 호출 및 예외가 차단되지 않을 때, 그것은 단지 프로세스를 종료합니다.

이것이 '좋은'종료 방법입니다. 아래의 @ glyphtwistedmatrix 는 '하드 엑시트'를 원한다면 os._exit(*errorcode*)어느 정도 운영 체제에 따라 다를 수 있지만 (예를 들어 Windows에서 오류 코드가 발생하지 않을 수 있음)을 사용할 수 있으며 , 그 때문에 친숙하지 않다는 점을 지적합니다. 프로세스가 종료되기 전에 인터프리터가 정리를 수행하도록 허용하지 않습니다.


9
아마도 sys.exit()백그라운드 스레드에 의해 발생하면 작동하지 않습니다 (프로세스를 죽이지 않고 스레드 만 죽입니다)?

@ cesium62 : 예, sys.exit()제기 SystemExit, 현재의 thread에 예외를.
Dmitry Trofimov

13
예외없이 스크립트를 종료 할 수있는 방법이 있습니까? 나는 이미 스크립트와 관련 플래그를 인쇄하여 스크립트를 popen에 stdout 파이프로 전달하고 있으므로이 경우 예외는 해결하는 것보다 더 많은 문제를 일으 킵니다.
Elliot

4
왜이 방법을 사용할 때 다음과 같은 경고 메시지가 나타납니다.UserWarning: To exit: use 'exit', 'quit', or Ctrl-D. warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
Bill

1
자세한 내용이 필요합니다. 아마도 그것은 그 자신의 질문이 될 가치가 있습니까?
pjz

349

파이썬 스크립트를 조기에 종료하는 간단한 방법은 내장 quit()함수 를 사용하는 것입니다. 라이브러리를 가져올 필요가 없으며 효율적이고 간단합니다.

예:

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

86
또한 sys.exit ()는 모든 파이썬 스크립트를 종료하지만 quit ()는 스크립트를 생성 한 스크립트 만 종료합니다.
VishalDevgire

4
이 명령이 파이썬 2와 파이썬 3에서 다르게 작동하는지 알고 있습니까?
David C.

1
이것이 전체 인터프리터를 종료하거나 스크립트 실행을 중지 시킬지 아는 사람이 있습니까? 구체적으로 : Spyder에서 실행되는 스크립트의 경우 Python 인터프리터가 대화식으로 유지됩니까? 아니면 죽입니까? 스크립트가 계속되는 것을 멈추고 인터프리터 인터랙티브를 유지하십시오.
Demis

3
나를 위해 'quit'이 정의되어 있지 않다고 말합니다. 나는 파이썬 3을 사용하고 있습니다.
Vincenzooo

4
나는 파이썬 3.7에 있고 quit ()은 인터프리터를 멈추고 스크립트를 닫습니다.
RockAndRoleCoder 5

120

다른 방법은 다음과 같습니다.

raise SystemExit

36
@Alessa : 더 우아해 보이지만 권장하지 않습니다 : 선호하는 (쓰기 가능한) sys.exit래퍼 대신 내장 예외를 직접 발생시키고 있습니다.
MestreLion

1
이것은 나에게 완벽한 방법입니다. 실행중인 스크립트를 종료하고 IDLE을 종료하지 마십시오
rml

77

간단하게 사용할 수도 있습니다 exit().

있다는 사실을 숙지 sys.exit(), exit(), quit(), 및 os._exit(0) 죽일 파이썬 인터프리터를. 따라서에 의해 다른 스크립트에서 호출 된 스크립트에 표시 execfile()되면 두 스크립트의 실행이 중지됩니다.

이를 피하려면 " execfile로 호출 된 스크립트 실행 중지 "를 참조하십시오 .


67

일반적으로 sys.exit다른 코드에 비해 "친숙"하기 때문에 선호하지만 실제로는 예외를 발생시키는 것뿐입니다.

프로세스를 즉시 종료해야하고 catch 할 예외 처리기 내부에있을 수 있는 경우 C 수준에서 즉시 종료되고 정상적인 해체를 수행하지 않는 SystemExit다른 함수 os._exit가 있습니다 통역사; 예를 들어 "atexit"모듈에 등록 된 후크는 실행되지 않습니다.


43

난 그냥 multithreadded 응용 프로그램을 작성할 때 사실을 발견했습니다 raise SystemExitsys.exit()모두는 실행중인 스레드를 죽인다. 반면에 os._exit()전체 프로세스를 종료합니다. 이것은 " 파이썬의 스레드 안에서 호출 될 때 sys.exit ()가 종료되지 않는 이유는 무엇입니까? "에서 논의되었습니다 .

아래 예에는 2 개의 스레드가 있습니다. 케니와 카트 맨 카트 만은 영원히 살기로되어 있지만 케니는 재귀 적으로 불려지고 3 초 후에 죽어야합니다. (재귀 호출이 가장 좋은 방법은 아니지만 다른 이유가 있습니다)

만약 Kenny가 죽었을 때 Cartman이 죽기를 원한다면 Kenny와 함께 가야합니다 os._exit. 그렇지 않으면 Kenny 만 죽고 Cartman은 영원히 살 것입니다.

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

1
잘 했어. 다른 답변은 여러 스레드를 직접 처리하지 않으며 다른 스크립트를 생성하는 스크립트 만 처리합니다.
익명의

33
from sys import exit
exit()

매개 변수로 종료 코드를 전달하면 OS로 리턴됩니다. 기본값은 0입니다.


3
내 경우에는 출구를 가져올 필요조차 없었습니다.
코스타 노스

5
그냥 위의 의견에 후손을위한 - exit()sys.exit()같은 것이 아니다. 내장 exit()된 스크립트를 사용하지 마십시오 . 이것은 대화식 쉘의 도우미 sys.exit()
일뿐입니다.

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 ()의 12 번 줄 "Z : \ Directory \ testdieprogram.py"파일, 메인 sys.exit (8 번 줄 "Z : \ Directory \ testdieprogram.py"파일 ) 시스템 종료

편집하다

요점은 프로그램이 "I 'VE STOPPED !!!!"이 아니라 부드럽고 평화롭게 끝난다는 것입니다.


20
하나의 문제는 중첩 된 함수에 있고 종료하려는 경우 최상위 함수로 플래그를 다시 보내거나 다음 단계로 돌아갑니다.
horta

11
return스크립트를 종료하는 데 사용할 수 있다고 제안하려는 경우 이것은 말도 안됩니다 . 모든 return것은 값과 제어 흐름을 호출 함수에 반환하는 것입니다. 호출 된 함수의 호출 직후에 실행이 계속됩니다 return. 물론, return예제에서와 같이 스크립트에서 마지막 명령문 인 경우 스크립트가 호출 된 직후 스크립트가 종료됩니다.
David Ferenczy Rogožan

1
이 접근법에 대해 강력한 논거가있다 : (1) 중간에서 "종료"는 틀림없이 "고토 (goto)"이다. (2) 라이브러리에서 "종료"는 분명히 나쁜 습관입니다 (그리고 무엇이든 라이브러리가 될 수 있습니다). 라이브러리가 "복구 할 수없는"것으로 간주 하는 것은 일반적으로 호출자에게 좋습니다. (참고 : 종료에 예외를 사용하는 것은 C / C ++ / Java 개발자에게 항상 부적절하게 호출하는 파이썬 실용적인 해결 방법입니다. exit따라서 파이썬 프로그래머는이 코드의 악취를 느끼지 못할 수도 있습니다). 마지막으로 (3) 멀티 스레드 코드 (pythonistas는 역사적으로 무시했습니다).
마이클

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!")

나는 응용 프로그램이 처리 할 수있는 오류에 대해 예외를 제기하는 것이 낫다는 것에 전적으로 동의합니다. 그러나 문제는 파이썬 스크립트를 종료하는 방법이므로 질문에 대한 (새로운) 답변은 아닙니다.
wovano

-1

내 두 센트

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

의견을 보내 주셔서 감사합니다. 이제 코드의 일부를 종료 문과 관련하여 추가했습니다.
마태 복음

좋아, 이것은 조금 더 많은 맥락을 제공합니다 :) 지금은 귀하의 솔루션이 실제로 매우 나쁜 프로그래밍 패턴에 대한 해결책이라고 생각합니다. 우선 except:예외 유형 없이는 사용해서는 안됩니다 . 방금 사용 except Exception:하거나 가능한 경우 더 자세한 예외 유형을 사용하면 sys.exit()의도 한대로 작동하므로이 해결 방법이 필요하지 않습니다.
wovano

둘째, 하나의 방법으로, 또는 심지어 전역 파일 범위에서 많은 일을하려고하는 것처럼 보입니다. (1) 입력 파일로드, (2) 프로세스 데이터 및 (3) 출력 파일 쓰기와 같이 코드를 더 작은 조각 (기능)으로 나누는 데 도움이됩니다. 그런 다음 1 단계가 실패하면 2 단계와 3 단계를 건너 뛰십시오.로드 단계 중 어느 곳에서나 예외를 발생시키고 한 곳에서 예외를 처리 할 수 ​​있습니다. 사용 sys.exit()은 실제로 중대한 오류에 대한 일종의 최후의 해결책입니다. 그냥 내 두 센트 :)
wovano

일반적으로 파이썬에서는 전역 종료 / 중지 기능이 표시되지 않으므로이 방법으로 만들어야합니다. CSV 파일은 나에게 매우 중요하므로 수단이보기 흉한 것처럼 보일지라도 가능한 한 항상 보호합니다. 스타일을 개선하기 위해 The Hichhicker 's Guide to Python 을 읽고 있습니다.
마태 복음
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.