2009-07-27 12 views
211

Me gustaría saber cómo salir de Python sin tener un volcado de rastreo en la salida.¿Cómo salir de Python sin rastreo?

Aún quiero querer poder devolver un código de error pero no quiero mostrar el registro de rastreo.

Quiero poder salir usando exit(number) sin dejar rastros, pero en caso de una excepción (no una salida) quiero el rastreo.

+6

sys.exit() detiene la ejecución sin imprimir una traza inversa, lo que provoca una excepción ... su pregunta describe exactamente cuál es el comportamiento predeterminado, por lo que no debe cambiar nada. –

+0

@Luper Es muy fácil comprobar que sys.exit() arroja SystemExit! – Val

+4

Dije que no imprime un rastreo, no es que no genere una excepción. –

Respuesta

238

Supuestamente se encuentra con una excepción y el programa se está saliendo debido a esto (con un rastreo). Por lo tanto, lo primero que debe hacer es detectar esa excepción antes de salir limpiamente (tal vez con un mensaje, ejemplo dado).

intentar algo como esto en su rutina 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() 
+2

Al principio debería haber algo como "desde la salida de importación de sys". –

+1

Hola Roberto: exit() está disponible sin importarlo, aunque también puedes importarlo desde sys. – jkp

+0

Tenga en cuenta que en las versiones anteriores de Python (antes 2.5), el comando 'exit' era una cadena simple no invocable. –

40
import sys 
sys.exit(1) 
10

algo así como import sys; sys.exit(0)?

+4

Votación descendente. Lanza SystemExit, que causa traceback – Val

+7

@Val: mal de nuevo. No hace rastreo – MestreLion

+0

@mestreLion Entonces, ¿por qué recibo Dets 06 18:53:17 Rastreo (llamada más reciente pasado): Archivo "debug_new.py", línea 4, en import sys; sys.exit (0) SystemExit: 0 en org.python.core.PyException.fillInStackTrace (PyException.java:70) en mi consola? – Val

64

Tal vez usted está tratando de capturar todas las excepciones y esto es para controlar el SystemExit excepción planteada por 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 

En general, el uso de except: sin nombrar a una excepción es una mala idea. Capturará todo tipo de cosas que no desea atrapar, como SystemExit, y también puede enmascarar sus propios errores de programación. Mi ejemplo anterior es tonto, a menos que esté haciendo algo en términos de limpieza. Se podría sustituirlo por:

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

Si necesita salir sin levantar SystemExit:

import os 
os._exit(1) 

hago esto, en el código que se ejecuta bajo unittest y llama fork(). Unittest se obtiene cuando el proceso bifurcado aumenta SystemExit. ¡Este es definitivamente un caso de esquina!

+2

-1: Este código es tonto: ¿por qué atrapar 'SystemExit' solo para llamar a' sys.exit (e) '? La eliminación de ambas líneas tiene el * mismo * efecto. Además, la limpieza pertenece a 'finally:', not 'except Exception: ... raise'. – MestreLion

+0

@MestreLion: Puedes votar downvote, pero si lees mi comentario justo arriba del tuyo, eso solo es válido para 2.5+. Si leíste toda mi publicación, explícitamente dije que el código es tonto y sugerí exactamente lo que dijiste en tu comentario. – bstpierre

+1

Lo siento, tienes razón ... Olvidé que había una importante reestructuración de excepciones en Python 2.5. Intenté deshacer el downvote, pero SO solo me permite hacerlo si la respuesta está editada. Entonces, dado que estamos en 2012 y Python 2.4 es historia antigua, ¿por qué no editarlo y mostrar el código correcto (actual) por adelantado, dejando el método pre-2.5 como nota al pie? Mejorará mucho la respuesta y podré deshacer el voto a la baja, y con mucho gusto lo haré.Ventaja para todos :) – MestreLion

-6
# 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

Si desea comentar el código, aumentaría la calidad de la respuesta. –

2

lo haría de esta manera:

import sys 

def do_my_stuff(): 
    pass 

if __name__ == "__main__": 
    try: 
     do_my_stuff() 
    except SystemExit, e: 
     print(e) 
3

Es una práctica mucho mejor evitar el uso de sys.exit() y en lugar de subir/manejar excepciones para permitir que el programa termine de forma limpia. Si desea desactivar el rastreo, sólo tiene que utilizar:

sys.trackbacklimit=0 

Es posible ajustar esta en la parte superior de su script para aplastar toda la salida de rastreo, pero prefiero utilizarlo con más moderación, por ejemplo, "los errores conocidos", donde Quiero que la salida esté limpia, por ejemplo en el archivo 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." 

Si CalledProcessError es capturado, la salida se verá así:

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

Si se produce cualquier otro error, todavía conseguimos la salida de rastreo completo.

+1

Para usar 'sys.trackbacklimit' en Python 3, vea [esta respuesta] (http://stackoverflow.com/a/21556806/832230). –

3

Utilice la función incorporada de pitón para salir() y eso es todo. No es necesario importar ninguna biblioteca. Estoy usando python 3.4

+1

Dice muy claramente en los [documentos] (https://docs.python.org/3/library/constants.html#quit) que cosas como 'quit' y' exit' no se deben usar en los programas. –

+1

Tienes razón, soy consciente de eso, pero mi impresión al leer la pregunta no fue que esté usando el guión para la producción, sino que pensé que estaba haciendo algunas pruebas para él o para algo. Bueno, lo he leído rápidamente, y tal vez debería haber señalado que no se debe usar quit() en los guiones de producción final. –