2009-08-06 10 views
6

Od docs Pythona:Jak ustawić sys.excepthook, aby wywoływać pdb globalnie w pythonie?

sys.excepthook(type, value, traceback)

Funkcja ta drukuje dany Traceback i wyjątków do sys.stderr.

Gdy wyjątek jest podnoszony i nie jest przechwytywany, interpreter wywołuje sys.excepthook z trzema argumentami, klasą wyjątków, instancją wyjątku i obiektem traceback. W sesji interaktywnej dzieje się to tuż przed zwróceniem kontroli do monitu; w programie Python dzieje się to tuż przed wyjściem programu. Obsługa takich wyjątków najwyższego poziomu może być dostosowana przez przypisanie innej funkcji trzech argumentów do sys.excepthook.

http://docs.python.org/library/sys.html

Jak zmodyfikować ten globalnie tak domyślną akcją jest zawsze powoływać pdb? Czy istnieje plik konfiguracyjny, który mogę zmienić? Nie chcę owijać mojego kodu, aby to zrobić.

Odpowiedz

17

Oto co trzeba

http://ynniv.com/blog/2007/11/debugging-python.html

Trzy sposoby, pierwszy jest prosty, ale surowy (Thomas Heller) - dodać następujące site-packages/sitecustomize.py:

import pdb, sys, traceback 
def info(type, value, tb): 
    traceback.print_exception(type, value, tb) 
    pdb.pm() 
sys.excepthook = info 

drugi jest bardziej wyrafinowany i sprawdza tryb interaktywny (dziwnie pomijając debugowanie w trybie interaktywnym), od cookbook:

# code snippet, to be included in 'sitecustomize.py' 
import sys 

def info(type, value, tb): 
    if hasattr(sys, 'ps1') or not sys.stderr.isatty(): 
     # we are in interactive mode or we don't have a tty-like 
     # device, so we call the default hook 
     sys.__excepthook__(type, value, tb) 
    else: 
     import traceback, pdb 
     # we are NOT in interactive mode, print the exception... 
     traceback.print_exception(type, value, tb) 
     print 
     # ...then start the debugger in post-mortem mode. 
     pdb.pm() 

sys.excepthook = info 

I trzeci (co zawsze uruchomić debugger chyba stdin lub stderr są przekierowywane) przez ynniv

# code snippet, to be included in 'sitecustomize.py' 
import sys 

def info(type, value, tb): 
    if (#hasattr(sys, "ps1") or 
     not sys.stderr.isatty() or 
     not sys.stdin.isatty()): 
     # stdin or stderr is redirected, just do the normal thing 
     original_hook(type, value, tb) 
    else: 
     # a terminal is attached and stderr is not redirected, debug 
     import traceback, pdb 
     traceback.print_exception(type, value, tb) 
     print 
     pdb.pm() 
     #traceback.print_stack() 

original_hook = sys.excepthook 
if sys.excepthook == sys.__excepthook__: 
    # if someone already patched excepthook, let them win 
    sys.excepthook = info 
+0

Dokładnie to, co chciałem, dziękuję. – saffsd

0

Spróbuj:

import pdb 
import sys 

def excepthook(type, value, traceback): 
    pdb.post_mortem(traceback) 

excepthook.old = sys.excepthook 
sys.excepthook = excepthook 

def raise_exception(): 
    raise_exception() 

raise_exception() 
+1

Nie sądzę, że nazwanie wywołującego pdb "excepthook" jest mądre. –

1

Inną opcją jest użycie ipython, które uważam za must-have narzędzie dla każdego dewelopera pythona. Zamiast uruchamiać skrypt z powłoki, uruchom go z ipython za pomocą% run. Gdy wystąpi wyjątek, możesz wpisać% debug, aby go zdebugować. (Jest też opcja automatycznego debugowania każdego wyjątku, ale nie pamiętam, co to jest.)