Как выйти из Python без трассировки?

277

Я хотел бы знать, как выйти из Python, не имея дамп трассировки на выходе.

Я все еще хочу иметь возможность вернуть код ошибки, но я не хочу отображать журнал трассировки.

Я хочу быть в состоянии выйти из использования exit(number)без трассировки, но в случае исключения (не выхода) я хочу трассировки.

Сорин
источник
8
sys.exit () останавливает выполнение без печати обратной трассировки, вызывает исключение ... ваш вопрос точно описывает поведение по умолчанию, поэтому ничего не меняйте.
Люпер Руш
@ Luper Очень легко проверить, что sys.exit () вызывает SystemExit!
Val
4
Я сказал, что это не печатает след, не то, чтобы это не вызывает исключение.
Luper Rouch
Я думаю, что это действительно отвечает на вопрос, который вы задали: stackoverflow.com/questions/173278/…
Stefan
2
Этот вопрос специально для Jython 2.4 или что-то в этом роде? Потому что для современных версий Python (даже в 2009 году, когда это означало CPython 2.6 и 3.1, Jython 2.5 и IronPython 2.6), этот вопрос не имеет смысла, и верхние ответы неверны.
abarnert

Ответы:

300

Вероятно, вы столкнулись с исключением, и программа завершает работу из-за этого (с отслеживанием). Поэтому первое, что нужно сделать, - это перехватить это исключение перед чистым выходом (возможно, с сообщением, приведенным примером).

Попробуйте что-то вроде этого в вашей mainповседневной жизни:

import sys, traceback

def main():
    try:
        do main program stuff here
        ....
    except KeyboardInterrupt:
        print "Shutdown requested...exiting"
    except Exception:
        traceback.print_exc(file=sys.stdout)
    sys.exit(0)

if __name__ == "__main__":
    main()
JKP
источник
2
В начале должно быть что-то вроде «из выхода sys import».
ограбить
10
Если sys.exit () вызывается в «основной программе», приведенный выше код отбрасывает значение, переданное в sys.exit. Обратите внимание, что sys.exit вызывает SystemExit, а переменная «e» будет содержать код выхода.
Bstpierre
5
я бы предложил распечатать в stderr sys.stderr.write (msg)
vinilios
14
Я настоятельно рекомендую удалить строки из except Exception:в sys.exit(0), включительно. Это уже поведение по умолчанию - выводить трассировку для всех необработанных исключений и выходить после завершения кода, так зачем же делать это вручную?
MestreLion
6
@jkp - По поводу вашего комментария: sys.exit()следует использовать для программ. exit()предназначен для интерактивных оболочек. Смотрите разницу между exit () и sys.exit () в Python? ,
ire_and_curses
81

Возможно, вы пытаетесь поймать все исключения, а это ловит SystemExitисключение, вызванное sys.exit()?

import sys

try:
    sys.exit(1) # Or something that calls sys.exit()
except SystemExit as e:
    sys.exit(e)
except:
    # Cleanup and reraise. This will print a backtrace.
    # (Insert your cleanup code here.)
    raise

В общем, использование except:без именования исключение является плохой идеей. Вы будете ловить все виды вещей, которые вы не хотите поймать - например, SystemExit- и это также может маскировать ваши собственные ошибки программирования. Мой пример выше глуп, если вы не делаете что-то с точки зрения очистки. Вы можете заменить его на:

import sys
sys.exit(1) # Or something that calls sys.exit().

Если вам нужно выйти без поднятия SystemExit:

import os
os._exit(1)

Я делаю это в коде, который работает под unittest и вызывает fork(). Unittest получает, когда разветвленный процесс повышается SystemExit. Это определенно угловой случай!

bstpierre
источник
4
-1: этот код глупый: зачем ловить, SystemExitчтобы просто позвонить sys.exit(e)? Удаление обеих строк имеет одинаковый эффект. Кроме того, очистка принадлежит finally:, а не except Exception: ... raise.
MestreLion
@MestreLion: Вы можете понизить голос, но если вы прочитаете мой комментарий чуть выше вашего, это верно только для 2.5+. Если вы прочитали все мои посты, я прямо сказал, что код глупый и предложил именно то, что вы сказали в своем комментарии.
bstpierre
2
Извините, вы правы ... Я забыл, что в Python 2.5 произошла серьезная реструктуризация исключений. Я попытался отменить отрицательное голосование, но ТАК позволяет мне сделать это, только если ответ отредактирован. Итак, поскольку мы находимся в 2012 году, а Python 2.4 является древней историей, почему бы не отредактировать его и не показать правильный (текущий) код заранее, оставив метод до 2.5 в качестве сноски? Это значительно улучшит ответ, и я смогу отменить отрицательное голосование, и с удовольствием это сделаю. Беспроигрышный для всех :)
MestreLion
@MestreLion: я начал редактировать, как вы предложили, но этот ответ действительно имеет смысл только в контексте вопроса и в среде 2.4. Падение не расстраивает меня.
bstpierre
9

что-то вроде import sys; sys.exit(0)?

грабить
источник
@mestreLion Тогда почему я получаю Dets 06 18:53:17 Traceback (последний вызов был последним): файл "debug_new.py", строка 4, в <module> import sys; sys.exit (0) SystemExit: 0 в org.python.core.PyException.fillInStackTrace (PyException.java:70) в моей консоли?
Val
3
@Val: потому что вы не используете стандартную консоль Python. Jython - это не Python, и, похоже, он (или, по крайней мере, его консоль) по-разному обрабатывает исключения.
MestreLion
4

Намного лучше избегать использования sys.exit () и вместо этого вызывать / обрабатывать исключения, чтобы позволить программе завершить работу без ошибок. Если вы хотите отключить трассировку, просто используйте:

sys.trackbacklimit=0

Вы можете установить это в верхней части вашего скрипта, чтобы подавить весь вывод трассировки, но я предпочитаю использовать его более экономно, например, «известные ошибки», где я хочу, чтобы вывод был чистым, например, в файле foo.py:

import sys
from subprocess import *

try:
  check_call([ 'uptime', '--help' ])
except CalledProcessError:
  sys.tracebacklimit=0
  print "Process failed"
  raise

print "This message should never follow an error."

Если CalledProcessError пойман, вывод будет выглядеть так:

[me@test01 dev]$ ./foo.py
usage: uptime [-V]
    -V    display version
Process failed
subprocess.CalledProcessError: Command '['uptime', '--help']' returned non-zero exit status 1

Если возникает какая-либо другая ошибка, мы все равно получаем полный вывод трассировки.

RCross
источник
1
Для использования sys.trackbacklimitв Python 3, смотрите этот ответ .
Acumenus
4

Используйте встроенную функцию python quit () и все. Нет необходимости импортировать любую библиотеку. Я использую Python 3.4

Miled Луи Ризк
источник
2

Я бы сделал это так:

import sys

def do_my_stuff():
    pass

if __name__ == "__main__":
    try:
        do_my_stuff()
    except SystemExit, e:
        print(e)
Карл В.
источник
0

Что о

import sys
....
....
....
sys.exit("I am getting the heck out of here!")

Нет трассировки и как-то более явно.

agcala
источник
-8
# Pygame Example  

import pygame, sys  
from pygame.locals import *

pygame.init()  
DISPLAYSURF = pygame.display.set_mode((400, 300))  
pygame.display.set_caption('IBM Emulator')

BLACK = (0, 0, 0)  
GREEN = (0, 255, 0)

fontObj = pygame.font.Font('freesansbold.ttf', 32)  
textSurfaceObj = fontObj.render('IBM PC Emulator', True, GREEN,BLACK)  
textRectObj = textSurfaceObj.get_rect()  
textRectObj = (10, 10)

try:  
    while True: # main loop  
        DISPLAYSURF.fill(BLACK)  
        DISPLAYSURF.blit(textSurfaceObj, textRectObj)  
        for event in pygame.event.get():  
            if event.type == QUIT:  
                pygame.quit()  
                sys.exit()  
        pygame.display.update()  
except SystemExit:  
    pass
Брайан Циммерман
источник
7
Если вы прокомментируете код, это повысит качество ответа.