2016-08-01 12 views
0

angezeigt wird Mein Verständnis ist: Normalerweise, wenn ein Fehler auftritt, wird es durch alle aufrufenden Funktionen geworfen und dann in der Konsole angezeigt. Jetzt gibt es einige Pakete, die ihre eigene Fehlerbehandlung durchführen, insbesondere GUI-bezogene Pakete zeigen oft überhaupt keine Fehler, sondern sie werden einfach weiter ausgeführt.Wie eine Fehlermeldung in mpl_connect() - Callback-Funktion

Wie können wir ein solches Verhalten im Allgemeinen außer Kraft setzen? Wenn ich GUI-Funktionen schreibe, würde ich gerne die Fehler sehen! Ich fand this post, wo es erklärt wird, wie es für den Fall von Tkinter zu tun ist. Wie kann das in Matplotlib gemacht werden?

Beispielcode:

import matplotlib.pyplot as plt 

def onclick(event): 
    print(event.x, event.y) 
    raise ValueError('SomeError') # this error is thrown but isn't displayed 

fig = plt.figure(5) 
fig.clf() 

try: # if figure was open before, try to disconnect the button 
    fig.canvas.mpl_disconnect(cid_button) 
except: 
    pass 
cid_button = fig.canvas.mpl_connect('button_press_event', onclick) 

Antwort

1

der Tat, wenn der Python-Interpreter eine Ausnahme trifft, die nie erwischt wird, wird es eine so genannte Zurückverfolgungs vor spannend stdout drucken. In der Regel fangen und verschlingen GUI-Pakete jedoch alle Ausnahmen, um zu verhindern, dass der Python-Interpreter aufregt. Sie möchten diese Rückverfolgung irgendwo anzeigen, aber im Fall von GUI-Anwendungen müssen Sie entscheiden, wo diese Rückverfolgung angezeigt werden soll. Die Standardbibliothek verfügt über ein Modul, das Ihnen bei der Arbeit mit einem solchen Traceback mit dem passenden Namen traceback10 hilft. Dann müssen Sie die Ausnahme abfangen, bevor das GUI-Toolkit dies tut. Ich kenne keine allgemeine Möglichkeit, einen Callback-Fehlerhandler einzufügen, aber Sie können jedem Callback manuell die Fehlerbehandlung hinzufügen. Am besten schreiben Sie einen Funktionsplaner, den Sie dann auf Ihren Callback anwenden.

import traceback, functools 

def print_errors_to_stdout(fun): 
    @functools.wraps(fun) 
    def wrapper(*args,**kw): 
     try: 
      return fun(*args,**kw) 
     except Exception: 
      traceback.print_exc() 
      raise 
    return wrapper 

@print_errors_to_stdout 
def onclick(event): 
    print(event.x, event.y) 
    raise ValueError('SomeError') 

Der Dekorateur print_errors_to_stdout nimmt eine Funktion und gibt eine neue Funktion, die die ursprüngliche Funktion in einem try ... except Block bettet und im Fall einer Ausnahme druckt die Rückverfolgung mit Hilfe von traceback.print_exc() nach stdout. (Der Wrapper selbst ist mit functools.wraps dekoriert, so dass die generierte Wrapper-Funktion unter anderem den Docstring der ursprünglichen Funktion behält). Wenn Sie das Traceback woanders zeigen möchten, geben Sie traceback.format_exc() einen String, den Sie dann irgendwo anzeigen/speichern könnten. Der Decorator reraised auch die Ausnahme, so dass das GUI-Toolkit immer noch die Möglichkeit hat, seine eigenen Aktionen auszuführen, typischerweise nur die Ausnahme zu verschlucken.

Verwandte Themen