2010-04-10 2 views
7

Wenn ich eine Laufzeitausnahme von der Standardbibliothek bekomme, ist es fast immer ein Problem in meinem Code und nicht im Bibliothekscode. Gibt es eine Möglichkeit, die Ausnahme-Stack-Ablaufverfolgung zu kürzen, so dass es die Eingeweide des Bibliothekspakets nicht anzeigt?Python: Beseitigung von Stapelspuren in Bibliothekscode?

Zum Beispiel würde Ich mag diese bekommen:

Traceback (most recent call last): 
    File "./lmd3-mkhead.py", line 71, in <module> 
    main() 
    File "./lmd3-mkhead.py", line 66, in main 
    create() 
    File "./lmd3-mkhead.py", line 41, in create 
    headver1[depotFile]=rev 
TypeError: Data values must be of type string or None. 

und nicht diese:

Traceback (most recent call last): 
    File "./lmd3-mkhead.py", line 71, in <module> 
    main() 
    File "./lmd3-mkhead.py", line 66, in main 
    create() 
    File "./lmd3-mkhead.py", line 41, in create 
    headver1[depotFile]=rev 
    File "/usr/anim/modsquad/oses/fc11/lib/python2.6/bsddb/__init__.py", line 276, in __setitem__ 
    _DeadlockWrap(wrapF) # self.db[key] = value 
    File "/usr/anim/modsquad/oses/fc11/lib/python2.6/bsddb/dbutils.py", line 68, in DeadlockWrap 
    return function(*_args, **_kwargs) 
    File "/usr/anim/modsquad/oses/fc11/lib/python2.6/bsddb/__init__.py", line 275, in wrapF 
    self.db[key] = value 
TypeError: Data values must be of type string or None. 

Update: hinzugefügt, um eine answer mit dem Code, durch den Zeiger von Alex.

Antwort

2

Dank den Zeiger von Alex, hier teh codez:

def trimmedexceptions(type, value, tb, pylibdir=None, lev=None): 
    """trim system packages from the exception printout""" 
    if pylibdir is None: 
     import traceback, distutils.sysconfig 
     pylibdir = distutils.sysconfig.get_python_lib(1,1) 
     nlev = trimmedexceptions(type, value, tb, pylibdir, 0) 
     traceback.print_exception(type, value, tb, nlev) 
    else: 
     fn = tb.tb_frame.f_code.co_filename 
     if tb.tb_next is None or fn.startswith(pylibdir): 
      return lev 
     else: 
      return trimmedexceptions(type, value, tb.tb_next, pylibdir, lev+1) 

import sys 
sys.excepthook=trimmedexceptions 

# --- test code --- 

def f1(): f2() 
def f2(): f3() 
def f3(): 
    import xmlrpclib 
    proxy = xmlrpclib.ServerProxy('http://nosuchserver') 
    proxy.f() 

f1() 

Welche diese Stack-Trace ergibt:

Traceback (most recent call last): 
    File "./tsttraceback.py", line 47, in <module> 
    f1() 
    File "./tsttraceback.py", line 40, in f1 
    def f1(): f2() 
    File "./tsttraceback.py", line 41, in f2 
    def f2(): f3() 
    File "./tsttraceback.py", line 45, in f3 
    proxy.f() 
gaierror: [Errno -2] Name or service not known 
0

Geben Sie einen unqualifizierten Versuch ein ... außer oben in Ihrem Code (zB: in Ihrem "main") oder sys.excepthook. Sie können dann den Stack-Trace formatieren, wie Sie möchten.

1

Die Traceback library ist wahrscheinlich, was Sie wollen. Hier ist ein Beispiel, die helfen könnten:

import traceback 

try: 
    your_main() 
except: 
    lines = traceback.format_exc() 
    print lines[:lines.find('File "/usr')] 

(Dies wird sich natürlich nicht, wenn es eine Ausnahme außerhalb der Bibliothek, und möglicherweise nicht genau Ihren Bedürfnissen passen, aber es ist eine Möglichkeit, die Traceback-Bibliothek verwenden)

10

Das Modul traceback in der Python-Standardbibliothek ermöglicht das Ausgeben von Fehler-Tracebacks auf eine Weise, die Ihren Vorstellungen entspricht, während sich eine Ausnahme verbreitet. Sie können diese Leistung entweder im except Abschnitt einer try/except Anweisung oder in einer Funktion, die Sie als sys.excepthook installiert haben, verwenden, die aufgerufen wird, wenn und wenn eine Ausnahme den ganzen Weg verbreitet; die Dokumentation zu zitieren:

In einer interaktiven Sitzung dies geschieht kurz vor der Steuerung an den prompt zurückgegeben wird; In einem Python-Programm passiert dies kurz bevor das Programm beendet wird. Die Behandlung solcher Top-Level- Ausnahmen kann angepasst werden, indem eine weitere dreiargumentale Funktion zu sys.excepthook zuweisen.

Hier ist ein einfaches, künstliches Beispiel:

>>> import sys 
>>> import traceback 
>>> def f(n): 
... if n<=0: raise ZeroDivisionError 
... f(n-1) 
... 
>>> def excepthook(type, value, tb): 
... traceback.print_exception(type, value, tb, 3) 
... 
>>> sys.excepthook = excepthook 
>>> f(8) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 3, in f 
    File "<stdin>", line 3, in f 
ZeroDivisionError 

wie Sie sehen, ohne einen try/except zu benötigen, können Sie die Traceback zu (zum Beispiel) leicht begrenzen können die ersten drei Ebenen - obwohl Wir wissen von Grund auf, dass es 9 verschachtelte Ebenen gab, als die Ausnahme ausgelöst wurde.

Sie wollen etwas anspruchsvoller als ein einfaches Limit auf Ebenen, so müssen Sie traceback.format_exception aufrufen, die Ihnen eine Liste von Zeilen gibt, anstatt es zu drucken, dann aus der Liste die Zeilen, die über Module sind Sie möchten nie in Ihren Tracebacks sehen und schließlich die restlichen Zeilen ausgeben (normalerweise sys.stderr, aber, was auch immer! -).

+0

reine destillierten Weisheit, mit einem Hauch von Stil gemischt ... Danke Alex! –

+0

@Mark, Gern geschehen - danke für die Anerkennung! –

Verwandte Themen