Bagaimana cara keluar dari Python tanpa traceback?


277

Saya ingin tahu cara keluar dari Python tanpa memiliki traceback dump pada output.

Saya masih ingin dapat mengembalikan kode kesalahan tetapi saya tidak ingin menampilkan log traceback.

Saya ingin dapat keluar menggunakan exit(number)tanpa jejak tetapi dalam kasus Pengecualian (bukan keluar) saya ingin jejak.


8
sys.exit () menghentikan eksekusi tanpa mencetak backtrace, meningkatkan Exception tidak ... pertanyaan Anda menjelaskan dengan tepat apa perilaku defaultnya, jadi jangan ubah apa pun.
Luper Rouch

@Luper Sangat mudah untuk memeriksa bahwa sys.exit () melempar SystemExit!
Val

4
Saya mengatakan itu tidak mencetak traceback, bukan karena itu tidak menimbulkan pengecualian.
Luper Rouch

Saya pikir ini benar-benar menjawab pertanyaan yang Anda ajukan: stackoverflow.com/questions/173278/…
Stefan

2
Apakah pertanyaan ini khusus untuk Jython 2.4 atau sesuatu seperti itu? Karena untuk versi Python modern (bahkan pada tahun 2009, ketika itu berarti CPython 2.6 dan 3.1, Jython 2.5, dan IronPython 2.6), pertanyaannya tidak masuk akal, dan jawaban teratas salah.
abarnert

Jawaban:


300

Anda mungkin menemukan pengecualian dan program keluar karena ini (dengan traceback). Karena itu, hal pertama yang harus dilakukan adalah menangkap pengecualian itu, sebelum keluar dengan bersih (mungkin dengan pesan, contoh yang diberikan).

Cobalah sesuatu seperti ini dalam mainrutinitas Anda :

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
Seharusnya ada sesuatu seperti "dari sys import exit" di awal.
merampok

10
Jika sys.exit () dipanggil dalam "program utama", kode di atas membuang nilai yang diteruskan ke sys.exit. Perhatikan bahwa sys.exit memunculkan SystemExit dan variabel "e" akan berisi kode keluar.
bstpierre

5
Saya akan menyarankan mencetak di stderr sys.stderr.write (msg)
vinilios

14
Saya sangat menyarankan menghapus baris dari except Exception:ke sys.exit(0), inklusif. Sudah merupakan perilaku default untuk mencetak traceback pada semua pengecualian yang tidak ditangani, dan untuk keluar setelah kode berakhir, jadi mengapa repot-repot melakukan hal yang sama secara manual?
MestreLion

6
@jkp - Mengenai komentar Anda: sys.exit()harus digunakan untuk program. exit()dimaksudkan untuk shell interaktif. Lihat Perbedaan antara exit () dan sys.exit () dalam Python? .
ire_and_curses

81

Mungkin Anda mencoba menangkap semua pengecualian dan ini menangkap SystemExitpengecualian yang diajukan 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

Secara umum, menggunakan except:tanpa menyebutkan pengecualian adalah ide yang buruk. Anda akan menangkap semua jenis barang yang tidak ingin Anda tangkap - seperti SystemExit- dan juga bisa menutupi kesalahan pemrograman Anda sendiri. Contoh saya di atas konyol, kecuali Anda melakukan sesuatu dalam hal pembersihan. Anda bisa menggantinya dengan:

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

Jika Anda perlu keluar tanpa menaikkan SystemExit:

import os
os._exit(1)

Saya melakukan ini, dalam kode yang berjalan di bawah unittest dan panggilan fork(). Unittest mendapat ketika proses bercabang meningkat SystemExit. Ini jelas merupakan kasus sudut!


4
-1: Kode ini konyol: mengapa menangkap SystemExithanya untuk menelepon sys.exit(e)? Menghapus kedua garis memiliki efek yang sama . Juga, pembersihan milik finally:, tidak except Exception: ... raise.
MestreLion

@MestreLion: Anda bebas untuk melakukan downvote, tetapi jika Anda membaca komentar saya tepat di atas Anda, itu hanya berlaku untuk 2.5+. Jika Anda membaca semua posting saya, saya secara eksplisit mengatakan bahwa kode itu konyol dan menyarankan apa yang Anda katakan dalam komentar Anda.
bstpierre

2
Maaf, Anda benar ... Saya lupa ada struktur ulang pengecualian di Python 2.5. Saya mencoba untuk membatalkan downvote, tetapi SO hanya memungkinkan saya untuk melakukannya jika jawabannya diedit. Jadi, karena kita berada di 2012 dan Python 2.4 adalah sejarah kuno, mengapa tidak mengeditnya dan menunjukkan kode yang benar (saat ini) di muka, meninggalkan metode pra-2.5 sebagai catatan kaki? Ini akan meningkatkan jawaban banyak dan saya akan dapat membatalkan downvote, dan dengan senang hati akan melakukannya. Menang-menang untuk semua orang :)
MestreLion

@MestreLion: Saya mulai mengedit seperti yang Anda sarankan, tetapi jawaban ini benar-benar hanya masuk akal dalam konteks pertanyaan dan lingkungan 2.4. Downvote tidak mengecewakan saya.
bstpierre


9

sesuatu seperti import sys; sys.exit(0)?


@mestreLion Lalu mengapa saya mendapatkan Dets 06 18:53:17 Traceback (panggilan terakhir terakhir): File "debug_new.py", baris 4, di <module> import sys; sys.exit (0) SystemExit: 0 di org.python.core.PyException.fillInStackTrace (PyException.java:70) di konsol saya?
Val

3
@ Val: karena Anda tidak menggunakan konsol python standar. Jython bukan Python, dan sepertinya (atau setidaknya konsolnya) menangani pengecualian secara berbeda.
MestreLion



4

Adalah praktik yang jauh lebih baik untuk menghindari penggunaan sys.exit () dan alih-alih memunculkan / menangani pengecualian agar program dapat selesai dengan bersih. Jika Anda ingin mematikan traceback, cukup gunakan:

sys.trackbacklimit=0

Anda dapat mengatur ini di bagian atas skrip Anda untuk menekan semua keluaran traceback, tetapi saya lebih suka menggunakannya lebih hemat, misalnya "kesalahan yang diketahui" di mana saya ingin hasilnya bersih, misalnya dalam file 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."

Jika CalledProcessError tertangkap, hasilnya akan terlihat seperti ini:

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

Jika ada kesalahan lain yang terjadi, kami masih mendapatkan hasil traceback penuh.


1
Untuk menggunakan sys.trackbacklimitdalam Python 3, lihat jawaban ini .
Acumenus

4

Gunakan fungsi python built-in quit () dan hanya itu. Tidak perlu mengimpor perpustakaan apa pun. Saya menggunakan python 3.4


2

Saya akan melakukannya dengan cara ini:

import sys

def do_my_stuff():
    pass

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

0

Bagaimana dengan

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

Tidak ada traceback dan entah bagaimana lebih eksplisit.


-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
Jika Anda berkomentar kode, itu akan meningkatkan kualitas jawabannya.
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.