Odpowiedzi:
import sys
sys.exit()
szczegóły z sys
dokumentacji modułu :
sys.exit([arg])
Wyjdź z Pythona. Jest to realizowane przez podniesienie
SystemExit
wyjątku, więc działania czyszczące określone w klauzulachtry
instrukcji wreszcie są honorowane i możliwe jest przechwycenie próby wyjścia na poziomie zewnętrznym.Opcjonalnym argumentem arg może być liczba całkowita podająca status wyjścia (domyślnie zero) lub inny typ obiektu. Jeśli jest liczbą całkowitą, zero jest uważane za „pomyślne zakończenie”, a każda niezerowa wartość jest uważana za „nienormalne zakończenie” przez powłoki i tym podobne. Większość systemów wymaga, aby znajdowała się w przedziale 0–127, aw przeciwnym razie daje niezdefiniowane wyniki. Niektóre systemy mają konwencję nadawania określonych znaczeń określonym kodom wyjścia, ale są one na ogół słabo rozwinięte; Programy uniksowe zwykle używają 2 dla błędów składni wiersza poleceń i 1 dla wszystkich innych rodzajów błędów. Jeśli przekazany zostanie inny typ obiektu, Żaden nie jest równoważny przekazaniu zera, a każdy inny obiekt jest drukowany do
stderr
i powoduje kod wyjścia 1. W szczególności,sys.exit("some error message")
to szybki sposób na zamknięcie programu w przypadku wystąpienia błędu.Ponieważ
exit()
ostatecznie „tylko” wywołuje wyjątek, proces zostanie zakończony dopiero po wywołaniu z głównego wątku, a wyjątek nie zostanie przechwycony.
Pamiętaj, że jest to „miły” sposób na wyjście. @ glyphtwistedmatrix poniżej wskazuje, że jeśli chcesz „twardego wyjścia”, możesz go użyć os._exit(*errorcode*)
, chociaż prawdopodobnie jest on do pewnego stopnia specyficzny dla systemu operacyjnego (na przykład może nie brać kodu błędu w systemie Windows) i zdecydowanie jest mniej przyjazny, ponieważ jest nie pozwala tłumaczowi wykonać żadnego czyszczenia przed śmiercią procesu.
sys.exit()
podnosi SystemExit
wyjątek w bieżącym wątku.
UserWarning: To exit: use 'exit', 'quit', or Ctrl-D. warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
Prostym sposobem wcześniejszego zakończenia skryptu Python jest użycie wbudowanej quit()
funkcji. Nie ma potrzeby importowania żadnej biblioteki, a jest to wydajne i proste.
Przykład:
#do stuff
if this == that:
quit()
Możesz także użyć po prostu exit()
.
Należy pamiętać, że sys.exit()
, exit()
, quit()
, i os._exit(0)
zabić interpreter Pythona. Dlatego jeśli pojawia się w skrypcie wywoływanym z innego skryptu przez execfile()
, zatrzymuje wykonywanie obu skryptów.
Zobacz „ Zatrzymaj wykonywanie skryptu wywoływanego z plikiem wykonywalnym ”, aby tego uniknąć.
Chociaż ogólnie powinieneś preferować, sys.exit
ponieważ jest on bardziej „przyjazny” dla innego kodu, wszystko, co faktycznie robi, to podniesienie wyjątku.
Jeśli masz pewność, że musisz natychmiast wyjść z procesu i być może znajdujesz się w jakimś module obsługi wyjątków, który może się wyłapać SystemExit
, istnieje inna funkcja - os._exit
- która kończy się natychmiast na poziomie C i nie wykonuje żadnego normalnego usuwania tłumacza; na przykład haki zarejestrowane w module „atexit” nie są wykonywane.
Właśnie dowiedziałem się, że podczas pisania multithreadded aplikację, raise SystemExit
a sys.exit()
zarówno zabija tylko wątkiem. Z drugiej strony os._exit()
wychodzi z całego procesu. Zostało to omówione w „ Dlaczego sys.exit () nie kończy działania po wywołaniu wewnątrz wątku w Pythonie? ”.
Poniższy przykład ma 2 wątki. Kenny and Cartman. Cartman ma żyć wiecznie, ale Kenny jest nazywany rekurencyjnie i powinien umrzeć po 3 sekundach. (dzwonienie rekurencyjne nie jest najlepszym sposobem, ale miałem inne powody)
Jeśli chcemy również, aby Cartman umarł, gdy Kenny umiera, Kenny powinien odejść os._exit
, w przeciwnym razie tylko Kenny umrze, a Cartman będzie żył wiecznie.
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()
from sys import exit
exit()
Jako parametr możesz przekazać kod wyjścia, który zostanie zwrócony do systemu operacyjnego. Domyślnie 0.
exit()
i sys.exit()
to nie to samo. Nie używaj wbudowanych exit()
skryptów, jest to tylko pomocnik dla interaktywnej powłoki - użyjsys.exit()
Jestem całkowitym nowicjuszem, ale na pewno jest to czystsze i bardziej kontrolowane
def main():
try:
Answer = 1/0
print Answer
except:
print 'Program terminated'
return
print 'You wont see this'
if __name__ == '__main__':
main()
...
Program zakończony
niż
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()
...
Program zakończony Traceback (ostatnie ostatnie wywołanie): Plik „Z: \ Directory \ testdieprogram.py”, wiersz 12, w main () Plik „Z: \ Directory \ testdieprogram.py”, wiersz 8, w głównym sys.exit ( ) SystemExit
Edytować
Chodzi o to, że program kończy się płynnie i spokojnie, zamiast „ZATRZYMAŁEM SIĘ !!!!”
return
do zakończenia skryptu. Wszystko, co return
robi, to zwrócenie wartości i przepływ kontroli do funkcji wywołującej. Tam kontynuuje wykonywanie zaraz po wywołaniu funkcji, która wywołała return
. Oczywiście, jeśli return
jest to ostatnia instrukcja w twoim skrypcie, tak jak w twoim przykładzie, skrypt jest kończony zaraz po jego wywołaniu.
exit
- stąd programiści pythonowi mogą nie zauważyć smrodu tego kodu); i wreszcie (3) wielowątkowy kod (który pythoniści historycznie po prostu ignorowali).
W Pythonie 3.5 próbowałem włączyć podobny kod bez użycia modułów (np. Sys, Biopy) innych niż wbudowane, aby zatrzymać skrypt i wydrukować komunikat o błędzie moim użytkownikom. Oto mój przykład:
## 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
Później stwierdziłam, że bardziej zwięzłe jest po prostu zgłoszenie błędu:
## My example revised:
if "ATG" in my_DNA:
## <Do something & proceed...>
else:
raise ValueError("Start codon is missing! Check your DNA sequence!")
Moje dwa centy.
Python 3.8.1, Windows 10, 64-bit.
sys.exit()
nie działa bezpośrednio dla mnie.
Mam kilka następnych pętli.
Najpierw deklaruję zmienną boolowską, którą nazywam immediateExit
.
Tak więc na początku kodu programu piszę:
immediateExit = False
Następnie, zaczynając od najbardziej wewnętrznego (zagnieżdżonego) wyjątku pętli, piszę:
immediateExit = True
sys.exit('CSV file corrupted 0.')
Następnie przechodzę do bezpośredniej kontynuacji zewnętrznej pętli i zanim cokolwiek zostanie wykonane przez kod, piszę:
if immediateExit:
sys.exit('CSV file corrupted 1.')
W zależności od złożoności, czasami powyższe stwierdzenie należy powtórzyć również w wyjątkach, itp.
if immediateExit:
sys.exit('CSV file corrupted 1.5.')
Niestandardowy komunikat służy również do mojego osobistego debugowania, ponieważ liczby są w tym samym celu - aby zobaczyć, gdzie skrypt naprawdę się kończy.
'CSV file corrupted 1.5.'
W moim szczególnym przypadku przetwarzam plik CSV, którego nie chcę, aby oprogramowanie dotykało, jeśli oprogramowanie wykryje, że jest uszkodzony. Dlatego dla mnie bardzo ważne jest, aby wyjść z całego skryptu Python natychmiast po wykryciu możliwego uszkodzenia.
I postępując zgodnie ze stopniowym sys.exinging ze wszystkich pętli, udaje mi się to zrobić.
Pełny kod: (konieczne były pewne zmiany, ponieważ jest to zastrzeżony kod do zadań wewnętrznych):
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.')
except:
bez typu wyjątku. Jeśli po prostu użyjesz except Exception:
(lub nawet bardziej szczegółowy typ wyjątku, jeśli to możliwe), sys.exit()
będzie działać zgodnie z przeznaczeniem i nie będziesz potrzebować tego obejścia.
sys.exit()
jest naprawdę rodzajem ostatecznego rozwiązania krytycznych błędów. Tylko moje dwa centy :)
sys.exit()
nie działa (nie zabija procesu, po prostu zabija wątek), jeśli zostanie podniesiony przez wątek w tle?