Мне известно о команде die() в PHP, которая рано закрывает скрипт.
Как я могу сделать это в Python?






import sys
sys.exit()
подробности из Документация модуля sys:
sys.exit([arg])
Exit from Python. This is implemented by raising the
SystemExitexception, so cleanup actions specified by finally clauses oftrystatements are honored, and it is possible to intercept the exit attempt at an outer level.The optional argument arg can be an integer giving the exit status (defaulting to zero), or another type of object. If it is an integer, zero is considered “successful termination” and any nonzero value is considered “abnormal termination” by shells and the like. Most systems require it to be in the range 0-127, and produce undefined results otherwise. Some systems have a convention for assigning specific meanings to specific exit codes, but these are generally underdeveloped; Unix programs generally use 2 for command line syntax errors and 1 for all other kind of errors. If another type of object is passed, None is equivalent to passing zero, and any other object is printed to
stderrand results in an exit code of 1. In particular,sys.exit("some error message")is a quick way to exit a program when an error occurs.Since
exit()ultimately “only” raises an exception, it will only exit the process when called from the main thread, and the exception is not intercepted.
Обратите внимание, что это «хороший» способ выхода. @ глифткрученная матрица ниже указывает, что если вам нужен `` жесткий выход '', вы можете использовать os._exit(*errorcode*), хотя он, вероятно, в некоторой степени зависит от ОС (например, он может не принимать код ошибки под Windows), и он определенно менее дружелюбен, поскольку он не позволяет интерпретатору выполнять какую-либо очистку до того, как процесс завершится. С другой стороны, он делает убивает весь процесс, включая все запущенные потоки, в то время как sys.exit() (как сказано в документации) завершается только при вызове из основного потока, без других запущенных потоков.
@ cesium62: Да, sys.exit() вызывает исключение SystemExit в текущем потоке.
Есть ли способ завершить сценарий без создания исключения? Я уже передаю соответствующие флаги из сценария с print в stdout в Popen, поэтому исключение в этом случае вызывает больше проблем, чем решает.
Почему, когда я использую этот метод, я получаю следующее предупреждение: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D. warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
Нужны подробности; может быть, это заслуживает отдельного вопроса?
@Bill stackoverflow.com/questions/25007104/…
Если вы используете Tkinter, он не остановит корневой процесс mainLoop и отображаемое окно. Для этого вам понадобится дополнительная линия root.destroy().
в многопоточном env процесс не останавливается.
Другой способ:
raise SystemExit
@Alessa: это выглядит более элегантно, но это не рекомендуется: вы напрямую вызываете встроенное исключение вместо предпочтительной (и перезаписываемой) оболочки sys.exit
Для меня это идеальный способ: просто выйти из работающего скрипта, но не выходить из IDLE.
from sys import exit
exit()
В качестве параметра вы можете передать код выхода, который будет возвращен ОС. По умолчанию 0.
в моем случае мне даже не нужно было импортировать выход.
Просто для потомков по поводу вышеприведенного комментария - exit() и sys.exit() - это не одно и то же. Не используйте встроенный exit() в скриптах, это просто помощник для интерактивной оболочки - используйте sys.exit()
Хотя обычно вам следует предпочесть sys.exit, потому что он более «дружелюбен» по отношению к другому коду, все, что он на самом деле делает, это вызывает исключение.
Если вы уверены, что вам нужно немедленно выйти из процесса, и вы можете оказаться внутри какого-либо обработчика исключений, который перехватит SystemExit, есть еще одна функция - os._exit, которая немедленно завершается на уровне C и не выполняет никаких обычных разрывов. -забой переводчика; например, хуки, зарегистрированные в модуле "atexit", не выполняются.
Простой способ преждевременно завершить сценарий Python - использовать встроенную функцию quit(). Нет необходимости импортировать какую-либо библиотеку, это эффективно и просто.
Пример:
#do stuff
if this == that:
quit()
также sys.exit () завершит все сценарии python, но quit () завершит только сценарий, который его породил.
Вы знаете, работает ли эта команда по-разному в Python 2 и Python 3?
Кто-нибудь знает, выйдет ли это из всего интерпретатора или просто остановит выполнение скрипта? Конкретно: для скрипта, запущенного в Spyder, интерпретатор Python останется интерактивным или он будет убит? Попробуйте просто остановить выполнение сценария, но оставьте интерактивность интерпретатора.
для меня это говорит, что "бросить" не определено. Я использую Python 3.
Я использую python 3.7, и quit () останавливает интерпретатор и закрывает скрипт.
Согласно документацияquit() - это «полезен для оболочки интерактивного интерпретатора и не должен использоваться в программах».
Я использую Python 3.7 с Jupyter Lab, и мой скрипт торжественно проигнорировал как Quit (), так и Exit (). Какие-либо предложения?
Вы также можете использовать просто exit().
Имейте в виду, что sys.exit(), exit(), quit() и os._exit(0)убийство интерпретатор Python. Следовательно, если он появляется в сценарии, вызываемом из другого сценария execfile(), он останавливает выполнение обоих сценариев.
См. "Остановить выполнение скрипта, вызванного с помощью execfile", чтобы избежать этого.
Для меня os._exit (0) был для меня самым элегантным способом. Все остальные вызывали нежелательные ошибки
Я новичок, но, конечно, это чище и управляемее
def main():
try:
Answer = 1/0
print Answer
except:
print 'Program terminated'
return
print 'You wont see this'
if __name__ == '__main__':
main()
...
Program terminated
чем
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 terminated Traceback (most recent call last): File "Z:\Directory\testdieprogram.py", line 12, in main() File "Z:\Directory\testdieprogram.py", line 8, in main sys.exit() SystemExit
Редактировать
Дело в том, что программа завершается плавно и спокойно, а не "Я ОСТАНОВЛЕН !!!!"
Одна из проблем может заключаться в том, что если вы находитесь во вложенных функциях и просто хотите выйти, вам нужно либо отправить флаг полностью обратно в верхнюю функцию, либо вы просто вернетесь на следующий уровень выше.
Это полная чушь, если вы пытаетесь предложить использовать return для завершения сценария. Все, что делает return, - это возвращает значение и поток управления вызывающей функции. Там он продолжает выполнение сразу после вызова функции, которая вызвала return. Конечно, если return является последним оператором в вашем сценарии, как в вашем примере, сценарий завершается сразу после его вызова.
Есть веские аргументы в пользу этого подхода: (1) «выход» из середины, возможно, «goto», отсюда естественное отвращение; (2) «выход» в библиотеках определенно является плохой практикой (и что-либо может стать библиотекой), поскольку то, что библиотека считает «невосстановимым», обычно нормально для звонящий. (Примечание: использование исключений для выходов - это практический обходной путь python для разработчиков C / C++ / Java, которые всегда неправильно вызывают exit - следовательно, программисты на Python могут не заметить запах этого кода); и, наконец, (3) многопоточный код (который питонисты исторически просто игнорировали).
Я только что обнаружил, что при написании многопоточного приложения raise SystemExit и sys.exit() убивают только работающий поток. С другой стороны, os._exit() завершает весь процесс. Это обсуждалось в «Почему sys.exit () не завершается при вызове внутри потока в Python?».
В приведенном ниже примере 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()
Кажется, это единственный способ справиться с неприятно отложенными обратными вызовами! (т.е. многопоточные методы.)
Отличная работа. Ни один из других ответов напрямую не касается нескольких потоков, а только сценарии, порождающие другие сценарии.
В 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, так что это не совсем (новый) ответ на вопрос.
Мои два цента.
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 сразу после обнаружения возможного повреждения.
И после постепенного выхода из всех циклов мне это удается.
Полный код: (потребовались некоторые изменения, так как это проприетарный код для внутренних задач):
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.')
Спасибо за ваш вклад, но для меня этот ответ не имеет смысла. Поскольку вы публикуете только несколько фрагментов кода вместо полного примера, трудно понять, что вы имеете в виду. Имея только те строки кода, которые вы разместили здесь, сценарий немедленно завершится. Я могу только догадываться, что у вас есть блок try-catch, который улавливает исключение SystemExit, которое уже упоминалось в других ответах. Если бы вы переписали свой ответ с полным рабочим примером того, как вы должны чисто выйти из приложения (т.е. выполнив некоторые необходимые действия по завершению работы), я думаю, ваш пост может быть полезным дополнением.
Спасибо за ваш отзыв. Теперь я добавил часть кода, которая касается операторов выхода.
Хорошо, это дает немного больше контекста :) Хотя теперь я думаю, что ваше решение на самом деле является обходным решением для очень плохих шаблонов программирования. Прежде всего, вы никогда не должны использовать except: без исключения. Если вы просто используете except Exception: (или, если возможно, даже более подробный тип исключения), sys.exit() будет работать так, как задумано, и вам не понадобится этот обходной путь.
Во-вторых, похоже, что вы пытаетесь сделать довольно много вещей одним методом или, возможно, даже в глобальной области видимости файла. Это поможет разбить ваш код на более мелкие части (функции), например: (1) загрузить входной файл, (2) обработать данные и (3) записать выходной файл. Затем, если шаг 1 завершится неудачно, вы пропустите шаги 2 и 3. Вы можете вызвать исключение в любом месте на этапе загрузки и обработать исключение в одном месте. Использование sys.exit() - это своего рода последнее средство для устранения критических ошибок. Всего два цента :)
В общем, я не вижу в Python функции глобального выхода / остановки, и я вынужден сделать это таким образом. Файл CSV очень важен для меня, поэтому я охраняю его всеми возможными способами, даже если средства могут показаться некрасивыми. Я читаю Руководство Хичхикера по Python, чтобы улучшить свой стиль.
wovano, вы упомянули «очень плохие шаблоны программирования». Где я могу прочитать о хороших шаблонах программирования? Ваш ответ будет очень признателен.
Вы упомянули Hitchhiker's Guido в Python, и я вижу, что он упоминает, например, Дзен Python. По крайней мере, некоторые правила очень применимы к этому посту, ИМХО, хотя я понимаю, что для этого может потребоваться некоторый опыт. Есть много книг о шаблонах программирования, и, много читая на SO и других веб-сайтах, вы также многому научитесь. Вы также можете опубликовать свой код на Проверка кода и попросить обратную связь (примечание: только рабочий код, это не для справки по отладке).
Предположительно,
sys.exit()не работает (не убивает процесс, просто убивает поток), если он вызван фоновым потоком?