with - Manuell eine Exception in Python auslösen(werfen)




python timeout exception (4)

Wie kann ich manuell eine Ausnahme in Python auslösen / auslösen?

Verwenden Sie den spezifischsten Exception-Konstruktor, der Ihrem Problem semantisch entspricht .

Sei spezifisch in deiner Nachricht, zB:

raise ValueError('A very specific bad thing happened.')

Generische Ausnahmen nicht auslösen

Vermeiden Sie das Generieren einer generischen Ausnahme. Um es zu fangen, müssen Sie alle anderen spezifischeren Ausnahmen abfangen, die es ableiten.

Problem 1: Fehler verstecken

raise Exception('I know Python!') # Don't! If you catch, likely to hide bugs.

Beispielsweise:

def demo_bad_catch():
    try:
        raise ValueError('Represents a hidden bug, do not catch this')
        raise Exception('This is the exception you expect to handle')
    except Exception as error:
        print('Caught this error: ' + repr(error))

>>> demo_bad_catch()
Caught this error: ValueError('Represents a hidden bug, do not catch this',)

Problem 2: Wird nicht fangen

und spezifischere Fänge fangen die allgemeine Ausnahme nicht ein:

def demo_no_catch():
    try:
        raise Exception('general exceptions not caught by specific handling')
    except ValueError as e:
        print('we will not catch exception: Exception')


>>> demo_no_catch()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in demo_no_catch
Exception: general exceptions not caught by specific handling

Best Practices: Erklärung raise

Verwenden Sie stattdessen den spezifischsten Exception-Konstruktor, der Ihrem Problem semantisch entspricht .

raise ValueError('A very specific bad thing happened')

was natürlich auch zulässt, dass eine beliebige Anzahl von Argumenten an den Konstruktor übergeben wird:

raise ValueError('A very specific bad thing happened', 'foo', 'bar', 'baz') 

Auf diese Argumente args das Argument args im Exception-Objekt zu. Beispielsweise:

try:
    some_code_that_may_raise_our_value_error()
except ValueError as err:
    print(err.args)

Drucke

('message', 'foo', 'bar', 'baz')    

In Python 2.5 wurde ein echtes message zu BaseException hinzugefügt, um Benutzer dazu zu ermutigen, Exceptions zu unterklassieren und die Verwendung von Argumenten zu beenden. Die Einführung von message und die ursprüngliche Verwerfung von Argumenten wurde jedoch zurückgezogen .

Best Practices: except

Wenn Sie sich innerhalb einer except-Klausel befinden, möchten Sie beispielsweise protokollieren, dass ein bestimmter Fehlertyp aufgetreten ist, und dann erneut erhöhen. Der beste Weg dies zu tun, während der Stack-Trace beibehalten wird, ist die Verwendung einer bloßen Raise-Anweisung. Beispielsweise:

logger = logging.getLogger(__name__)

try:
    do_something_in_app_that_breaks_easily()
except AppError as error:
    logger.error(error)
    raise                 # just this!
    # raise AppError      # Don't do this, you'll lose the stack trace!

Ändere deine Fehler nicht ... aber wenn du darauf bestehst.

Sie können den Stacktrace (und den Fehlerwert) mit sys.exc_info() , aber das ist viel fehleranfälliger und hat Kompatibilitätsprobleme zwischen Python 2 und 3 , bevorzugen Sie einen bloßen raise zum erneuten Raise.

Um zu erklären - die sys.exc_info() gibt den Typ, Wert und Traceback zurück.

type, value, traceback = sys.exc_info()

Dies ist die Syntax in Python 2 - Beachten Sie, dass dies nicht mit Python 3 kompatibel ist:

    raise AppError, error, sys.exc_info()[2] # avoid this.
    # Equivalently, as error *is* the second object:
    raise sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]

Wenn Sie möchten, können Sie modifizieren, was mit Ihrer neuen Erhöhung geschieht - zB neue Argumente für die Instanz setzen:

def error():
    raise ValueError('oops!')

def catch_error_modify_message():
    try:
        error()
    except ValueError:
        error_type, error_instance, traceback = sys.exc_info()
        error_instance.args = (error_instance.args[0] + ' <modification>',)
        raise error_type, error_instance, traceback

Und wir haben den gesamten Traceback beibehalten, während wir die Argumente geändert haben. Beachten Sie, dass dies keine bewährte Methode ist und in Python 3 eine ungültige Syntax ist (wodurch die Kompatibilität wesentlich erschwert wird).

>>> catch_error_modify_message()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in catch_error_modify_message
  File "<stdin>", line 2, in error
ValueError: oops! <modification>

In Python 3 :

    raise error.with_traceback(sys.exc_info()[2])

Nochmals: Vermeiden Sie die manuelle Manipulation von Trace-Backs. Es ist weniger effizient und fehleranfällig. Und wenn Sie threading und sys.exc_info Sie möglicherweise sogar die falsche Traceback (vor allem, wenn Sie die Ausnahmebehandlung für den Kontrollfluss verwenden - was ich persönlich eher vermeiden würde.)

Python 3, Ausnahmeverkettung

In Python 3 können Sie Exceptions ketten, die Tracebacks beibehalten:

    raise RuntimeError('specific message') from error

Sei vorsichtig:

  • dies erlaubt es, den erhöhten Fehlertyp zu ändern und
  • Dies ist nicht kompatibel mit Python 2.

Veraltete Methoden:

Diese können sich leicht verstecken und sogar in den Produktionscode gelangen. Sie möchten eine Ausnahme auslösen, und wenn Sie sie ausführen, wird eine Ausnahme ausgelöst, die jedoch nicht beabsichtigt ist!

Gültig in Python 2, aber nicht in Python 3 ist Folgendes:

raise ValueError, 'message' # Don't do this, it's deprecated!

Nur in viel älteren Versionen von Python (2.4 und niedriger) gültig , können Sie immer noch Leute sehen, die Zeichenfolgen erhöhen:

raise 'message' # really really wrong. don't do this.

In allen modernen Versionen wird dadurch ein TypeError ausgelöst, weil Sie keinen BaseException-Typ auslösen. Wenn Sie nicht nach der richtigen Ausnahme suchen und nicht über einen Prüfer verfügen, der das Problem erkennt, könnte es in Produktion gehen.

Beispiel Verwendung

Ich rufe Exceptions ab, um Nutzer über meine API zu warnen, wenn sie sie falsch verwenden:

def api_func(foo):
    '''foo should be either 'baz' or 'bar'. returns something very useful.'''
    if foo not in _ALLOWED_ARGS:
        raise ValueError('{foo} wrong, use "baz" or "bar"'.format(foo=repr(foo)))

Erstellen Sie bei Bedarf eigene Fehlertypen

"Ich möchte absichtlich einen Fehler machen, so dass es in die Ausnahme gehen würde"

Sie können Ihre eigenen Fehlertypen erstellen, wenn Sie angeben möchten, dass etwas mit Ihrer Anwendung nicht stimmt. Unterordnen Sie einfach den entsprechenden Punkt in der Ausnahmehierarchie:

class MyAppLookupError(LookupError):
    '''raise this when there's a lookup error for my app'''

und Verwendung:

if important_key not in resource_dict and not ok_to_be_missing:
    raise MyAppLookupError('resource is missing, and that is not ok.')

Wie kann ich eine Ausnahme in Python auslösen, so dass sie später über einen except abgefangen werden kann?


Tu das NICHT . Eine nackte Exception ist absolut nicht das Richtige; siehe stattdessen share .

Ich kann nicht viel mehr Python als das bekommen:

raise Exception("I know python!")

Wenn Sie weitere Informationen benötigen, sehen Sie in der Dokumentation zu raise statement für python nach.


In Python3 gibt es 4 verschiedene Syntaxen für das Aufrufen von Ausnahmen:

1. raise exception 
2. raise exception (args) 
3. raise
4. raise exception (args) from original_exception

1. Raise Exception gegen 2. Raise Exception (Args)

Wenn Sie eine raise exception (args) , um eine Ausnahme args werden die args gedruckt, wenn Sie das Ausnahmeobjekt drucken (siehe Beispiel unten).

  #raise exception (args)
    try:
        raise ValueError("I have raised an Exception")
    except ValueError as exp:
        print ("Error", exp)     # Output -> Error I have raised an Exception 



  #raise execption 
    try:
        raise ValueError
    except ValueError as exp:
        print ("Error", exp)     # Output -> Error 

3. Erhöhung

raise Anweisung ohne Argumente hebt die letzte Ausnahme erneut auf. Dies ist nützlich, wenn Sie einige Aktionen ausführen müssen, nachdem Sie die Ausnahme abgefangen haben und sie dann erneut auslösen möchten. Wenn es zuvor keine Ausnahme gab raise löst die raise Anweisung TypeError Exception aus.

def somefunction():
    print("some cleaning")

a=10
b=0 
result=None

try:
    result=a/b
    print(result)

except Exception:            #Output ->
    somefunction()           #some cleaning
    raise                    #Traceback (most recent call last):
                             #File "python", line 8, in <module>
                             #ZeroDivisionError: division by zero

4. Exception (args) von original_exception auslösen

Diese Anweisung wird zum Erstellen einer Ausnahmekette verwendet, bei der eine Ausnahme, die als Reaktion auf eine andere Ausnahme ausgelöst wird, die Details der ursprünglichen Ausnahme enthalten kann (siehe Beispiel unten).

class MyCustomException(Exception):
pass

a=10
b=0 
reuslt=None
try:
    try:
        result=a/b

    except ZeroDivisionError as exp:
        print("ZeroDivisionError -- ",exp)
        raise MyCustomException("Zero Division ") from exp

except MyCustomException as exp:
        print("MyException",exp)
        print(exp.__cause__)

Ausgabe:

ZeroDivisionError --  division by zero
MyException Zero Division 
division by zero

Lesen Sie zuerst die vorhandenen Antworten, dies ist nur ein Addendum.

Beachten Sie, dass Sie Ausnahmen mit oder ohne Argumente auslösen können.

Beispiel:

raise SystemExit

beendet das Programm, aber Sie möchten wissen, was passiert ist.So können Sie dies verwenden.

raise SystemExit("program exited")

Dies wird "Programm beendet" an stderr vor dem Schließen des Programms drucken.





exception-handling