2009-08-05 67 views

回答

0
try: 
    # blah blah The Main Loop, function, whatever... 
except e: 
    do_something_with(str(e)) 
+4

我猜你的意思是「除例外,E:」 ...... – 2009-08-06 01:55:37

2
import sys, logging 

logging.basicConfig(filename='/path/to/log/file', filemode='w')  
... 

try: 
    your_code_here() 
except: 
    logging.exception("My code failed") # logs exception to file 
    # you define display_exception_in_ui as "def display_exception_in_ui(exc, tb):" 
    display_exception_in_ui(*sys.exc_info()[1:]) # passes exception instance, traceback 
15

使用sys.excepthook更換基本異常處理程序。你可以這樣做:

import sys 
from PyQt4 import QtGui 

import os.path 
import traceback 

def handle_exception(exc_type, exc_value, exc_traceback): 
    """ handle all exceptions """ 

    ## KeyboardInterrupt is a special case. 
    ## We don't raise the error dialog when it occurs. 
    if issubclass(exc_type, KeyboardInterrupt): 
    if QtGui.qApp: 
     QtGui.qApp.quit() 
    return 

    filename, line, dummy, dummy = traceback.extract_tb(exc_traceback).pop() 
    filename = os.path.basename(filename) 
    error = "%s: %s" % (exc_type.__name__, exc_value) 

    QtGui.QMessageBox.critical(None,"Error", 
    "<html>A critical error has occured.<br/> " 
    + "<b>%s</b><br/><br/>" % error 
    + "It occurred at <b>line %d</b> of file <b>%s</b>.<br/>" % (line, filename) 
    + "</html>") 

    print "Closed due to an error. This is the full error report:" 
    print 
    print "".join(traceback.format_exception(exc_type, exc_value, exc_traceback)) 
    sys.exit(1) 



# install handler for exceptions 
sys.excepthook = handle_exception 

這捕獲所有未處理的異常,所以你並不需要在你的代碼的頂層一個try ... except塊。

+2

它緩存在主線程所有未處理的異常,但如果你使用線程模塊,threading.Thread都有自己的try /除了處理這繞開sys.excepthook。請參閱http://bugs.python.org/issue1230540。 – metamatt 2013-07-05 07:06:22

9

您已經得到了很好的答案,我只是想補充一個多年來以多種語言爲我提供的技巧,以便針對特定問題「如何幹淨地診斷,記錄日誌等,01​​錯誤?」。問題是,如果你的代碼在有足夠的對象被銷燬並且它們的內存被回收之前得到了控制,那麼內存可能太緊以致無法進行資產記錄,GUI工作等等 - 我們如何確保這種情況不會發生?

答:建立一個緊急藏匿處,所以你知道你可以花錢在這樣的緊急情況:

rainydayfund = [[] for x in xrange(16*1024)] # or however much you need 

def handle_exception(e): 
    global rainydayfund 
    del rainydayfund 
    ... etc, etc ... 
0

我試着用Neil's answer,但它不具有Tkinter的GUI工作。爲此,我不得不override report_callback_exception()

import Tkinter as tk 
import tkMessageBox 
import traceback 

class MyApp(tk.Frame): 
    def __init__(self, parent, *args, **kwargs): 
     tk.Frame.__init__(self, parent, *args, **kwargs) 
     parent.report_callback_exception = self.report_callback_exception 
     self.parent = parent 
     self.button_frame = tk.Frame(self) 
     self.button_frame.pack(side='top') 
     self.button_run = tk.Button(
      self.button_frame, text="Run", command=self.run 
     ) 
     self.button_run.grid(row=0, column=1, sticky='W') 

    def run(self): 
     tkMessageBox.showinfo('Info', 'The process is running.') 
     raise RuntimeError('Tripped.') 

    def report_callback_exception(self, exc_type, exc_value, exc_traceback): 
     message = ''.join(traceback.format_exception(exc_type, 
                exc_value, 
                exc_traceback)) 
     tkMessageBox.showerror('Error', message) 

def main(): 
    root = tk.Tk() # parent widget 

    MyApp(root).pack(fill='both', expand=True) 

    root.mainloop() # enter Tk event loop 

if __name__ == '__main__': 
    main()