20

W języku Python, jaki jest najlepszy sposób na wychwycenie "wszystkich" wyjątków?Łapanie wszystkich wyjątków w Pythonie

except: # do stuff with sys.exc_info()[1] 

except BaseException as exc: 

except Exception as exc: 

Połów może być wykonywany w wątku.

Moim celem jest, aby zalogować się żadnych wyjątków, które mogą zostać wyrzucone przez zwykłego kodu bez maskowania żadnych specjalnych wyjątków Python, takie jak te, które wskazują na zakończenie procesu itd

uzyskiwanie uchwyt do wyjątku (na przykład poprzez klauzule powyżej, które zawierają exc) jest również pożądane.

Odpowiedz

20

Jeśli trzeba złapać wszystkie wyjątki i robić te same rzeczy dla wszystkich, ja ci proponuję to:

try: 
    #stuff 
except: 
    # do some stuff 

Jeśli nie chcesz, aby zamaskować „Special” wyjątki Python, użyj Exception Klasa bazowa

try: 
    #stuff 
except Exception: 
    # do some stuff 

dla niektórych wyjątków dotyczących zarządzania, złapać je wyraźnie:

try: 
    #stuff 
except FirstExceptionBaseClassYouWantToCatch as exc: 
    # do some stuff 
except SecondExceptionBaseClassYouWantToCatch as exc: 
    # do some other stuff based 
except (ThirdExceptionBaseClassYouWantToCatch, FourthExceptionBaseClassYouWantToCatch) as exc: 
    # do some other stuff based 

The exception hierarchy z dokumentacji python powinien być przydatny do czytania.

+1

Dzięki za link do hierarchii wyjątku. :) – EOL

0

Aby uniknąć maskowania podstawowych wyjątków, musisz "przeindeksować" wszystkie wyjątki, które nie są tymi, które wyraźnie chcesz obsłużyć, np. (Dostosowane z 8. Errors and Exceptions)

 
import sys

try: # do something that could throw an exception: except IOError as (errno, strerror): print "I/O error({0}): {1}".format(errno, strerror) except ValueError: print "Could not convert data to an integer." except: # maybe log the exception (e.g. in debug mode) # re-raise the exception: raise

+1

Ostatnie 'except: raise' nic nie robi: można go całkowicie pominąć; Wyjątki bez IOError i Non-ValueError po prostu nie są przechwytywane i są automatycznie wywoływane przez interpreter. – EOL

+1

@EOL Masz rację. Zmieniłem moją odpowiedź, aby wskazać, dlaczego finał z wyjątkiem: może być przydatny. – Peter

29
  • except Exception: vs except BaseException::

    Różnica pomiędzy uchwyt Exception i BaseException jest to, że zgodnie z wyjątkiem jak SystemExit, KeyboardInterrupt i GeneratorExit exception hierarchy nie zostanie złapany podczas korzystania z except Exception, ponieważ dziedziczą bezpośrednio od BaseException.

  • except: vs except BaseException::

    Różnica między nimi jest głównie pytona 2 (AFAIK), i tylko przy użyciu starego klasy styl jako wyjątek być podniesiona, w tym przypadku tylko wyrażenie mniej Klauzula except będzie w stanie wychwycić wyjątek, np.

    class NewStyleException(Exception): pass 
    
    try: 
        raise NewStyleException 
    except BaseException: 
        print "Caught" 
    
    class OldStyleException: pass 
    
    try: 
        raise OldStyleException 
    except BaseException: 
        print "BaseException caught when raising OldStyleException" 
    except: 
        print "Caught" 
    
+2

Zrobiłem 'NewStyleException' dziedziczy po' Exception', co jest oficjalnie zalecane (http://docs.python.org/tutorial/errors.html#user-defined-exceptions). – EOL

Powiązane problemy