webentwicklung-frage-antwort-db.com.de

Wie kann ich diese Ausnahme mit einer anerkannten Nachricht in Python auslösen?

Ich habe diesen try-Block in meinem Code:

try:
    do_something_that_might_raise_an_exception()
except ValueError as err:
    errmsg = 'My custom error message.'
    raise ValueError(errmsg)

Streng genommen ziehe ich eine andereValueError an, nicht die von do_something...() geworfene ValueError, die in diesem Fall als err bezeichnet wird. Wie füge ich eine benutzerdefinierte Nachricht an err an? Ich versuche den folgenden Code, schlägt jedoch fehl, weil err, eine ValueError Instanz nicht aufgerufen werden kann:

try:
    do_something_that_might_raise_an_exception()
except ValueError as err:
    errmsg = 'My custom error message.'
    raise err(errmsg)
97
Kit

Update: Für Python 3 überprüfen Sie Bens Antwort


So hängen Sie eine Nachricht an die aktuelle Ausnahme an und rufen sie erneut auf: (Der äußere Versuch/die Ausnahme ist nur zur Darstellung des Effekts)

Für Python 2.x mit x> = 6:

try:
    try:
      raise ValueError  # something bad...
    except ValueError as err:
      err.message=err.message+" hello"
      raise              # re-raise current exception
except ValueError as e:
    print(" got error of type "+ str(type(e))+" with message " +e.message)

Dies wird auch das richtige tun , wenn errabgeleitet von ValueError ist. Zum Beispiel UnicodeDecodeError

Beachten Sie, dass Sie err hinzufügen können, was Sie möchten. Zum Beispiel err.problematic_array=[1,2,3].


Edit: @Ducan Punkte in einem Kommentar, das oben nicht mit Python 3 funktioniert, da .message kein Mitglied von ValueError ist. Stattdessen können Sie Folgendes verwenden (gültiger Python 2.6 oder höher oder 3.x):

try:
    try:
      raise ValueError
    except ValueError as err:
       if not err.args: 
           err.args=('',)
       err.args = err.args + ("hello",)
       raise 
except ValueError as e:
    print(" error was "+ str(type(e))+str(e.args))

Edit2:

Je nach Zweck können Sie die zusätzlichen Informationen auch unter Ihrem eigenen Variablennamen hinzufügen. Für beide, Python2 und Python3:

try:
    try:
      raise ValueError
    except ValueError as err:
       err.extra_info = "hello"
       raise 
except ValueError as e:
    print(" error was "+ str(type(e))+str(e))
    if 'extra_info' in dir(e):
       print e.extra_info
68
Johan Lundberg

Mir ist klar, dass diese Frage schon eine Weile existiert, aber wenn Sie nur Python 3.x unterstützen, wird dies wirklich eine schöne Sache :)

erhöhen von

Wir können die Ausnahmen mit raise von verketten.

try:
    1 / 0
except ZeroDivisionError as e:
    raise Exception('Smelly socks') from e

In diesem Fall hat die Ausnahme, die Ihr Anrufer auffangen würde, die Leitungsnummer des Ortes, an dem wir unsere Ausnahme melden.

Traceback (most recent call last):
  File "test.py", line 2, in <module>
    1 / 0
ZeroDivisionError: division by zero

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "test.py", line 4, in <module>
    raise Exception('Smelly socks') from e
Exception: Smelly socks

Beachten Sie, dass die untere Ausnahme nur den Stacktrace enthält, von dem aus wir die Ausnahme ausgelöst haben. Ihr Anrufer könnte trotzdem die ursprüngliche Ausnahme erhalten, indem er auf das __cause__-Attribut der Ausnahme zugreifen, die er abfängt.

with_traceback

Oder Sie können with_traceback verwenden.

try:
    1 / 0
except ZeroDivisionError as e:
    raise Exception('Smelly socks').with_traceback(e.__traceback__)

Bei Verwendung dieses Formulars hat die Ausnahme, die Ihr Aufrufer abfangen würde, das Traceback, ab dem der ursprüngliche Fehler aufgetreten ist.

Traceback (most recent call last):
  File "test.py", line 2, in <module>
    1 / 0
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test.py", line 4, in <module>
    raise Exception('Smelly socks').with_traceback(e.__traceback__)
  File "test.py", line 2, in <module>
    1 / 0
Exception: Smelly socks

Beachten Sie, dass die untere Ausnahme die Zeile hat, in der wir die ungültige Division durchgeführt haben, sowie die Zeile, in der wir die Ausnahme erneut erhöhen.

104
Ben
try:
    try:
        int('a')
    except ValueError as e:
        raise ValueError('There is a problem: {0}'.format(e))
except ValueError as err:
    print err

druckt:

There is a problem: invalid literal for int() with base 10: 'a'
6
eumiro

Es scheint, dass alle Antworten Informationen zu e.args [0] hinzufügen, wodurch die vorhandene Fehlermeldung geändert wird. Gibt es einen Nachteil bei der Erweiterung des args-Tupels? Ich denke, der mögliche Nachteil besteht darin, dass Sie die ursprüngliche Fehlernachricht für Fälle lassen können, in denen eine Analyse der Zeichenfolge erforderlich ist. Sie könnten dem Tuple mehrere Elemente hinzufügen, wenn Ihre benutzerdefinierte Fehlerbehandlung mehrere Meldungen oder Fehlercodes erzeugt hat, für den Fall, dass das Traceback programmgesteuert analysiert werden würde (wie über ein Systemüberwachungstool).

## Approach #1, if the exception may not be derived from Exception and well-behaved:

def to_int(x):
    try:
        return int(x)
    except Exception as e:
        e.args = (e.args if e.args else Tuple()) + ('Custom message',)
        raise

>>> to_int('12')
12

>>> to_int('12 monkeys')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in to_int
ValueError: ("invalid literal for int() with base 10: '12 monkeys'", 'Custom message')

oder

## Approach #2, if the exception is always derived from Exception and well-behaved:

def to_int(x):
    try:
        return int(x)
    except Exception as e:
        e.args += ('Custom message',)
        raise

>>> to_int('12')
12

>>> to_int('12 monkeys')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in to_int
ValueError: ("invalid literal for int() with base 10: '12 monkeys'", 'Custom message')

Sehen Sie einen Nachteil dieses Ansatzes?

5
Chris Johnson

Mit dieser Codevorlage können Sie eine Ausnahme mit einer benutzerdefinierten Nachricht auslösen.

try:
     raise ValueError
except ValueError as err:
    raise type(err)("my message")
2
Ruggero Turra

Dies ist die Funktion, die ich zum Ändern der Ausnahmemeldung in Python 2.7 und 3.x verwende, während der ursprüngliche Traceback beibehalten wird. Es erfordert six

def reraise_modify(caught_exc, append_msg, prepend=False):
    """Append message to exception while preserving attributes.

    Preserves exception class, and exception traceback.

    Note:
        This function needs to be called inside an except because
        `sys.exc_info()` requires the exception context.

    Args:
        caught_exc(Exception): The caught exception object
        append_msg(str): The message to append to the caught exception
        prepend(bool): If True prepend the message to args instead of appending

    Returns:
        None

    Side Effects:
        Re-raises the exception with the preserved data / trace but
        modified message
    """
    ExceptClass = type(caught_exc)
    # Keep old traceback
    traceback = sys.exc_info()[2]
    if not caught_exc.args:
        # If no args, create our own Tuple
        arg_list = [append_msg]
    else:
        # Take the last arg
        # If it is a string
        # append your message.
        # Otherwise append it to the
        # arg list(Not as pretty)
        arg_list = list(caught_exc.args[:-1])
        last_arg = caught_exc.args[-1]
        if isinstance(last_arg, str):
            if prepend:
                arg_list.append(append_msg + last_arg)
            else:
                arg_list.append(last_arg + append_msg)
        else:
            arg_list += [last_arg, append_msg]
    caught_exc.args = Tuple(arg_list)
    six.reraise(ExceptClass,
                caught_exc,
                traceback)
2
Bryce Guinta

Rufen Sie entweder die neue Ausnahme mit der Fehlermeldung auf

raise Exception('your error message')

oder

raise ValueError('your error message')

an der Stelle, an der Sie die Meldung OR ausführen möchten, fügen Sie die Fehlernachricht mit "from" in die aktuelle Ausnahme ein:

except ValueError as e:
  raise ValueError('your message') from e
1

In Python 3 integrierte Ausnahmen haben das Feld strerror:

except ValueError as err:
  err.strerror = "New error message"
  raise err
1
user3761308

Die aktuelle Antwort funktionierte nicht gut für mich. Wenn die Ausnahme nicht erneut abgefangen wird, wird die angefügte Nachricht nicht angezeigt.

Wenn Sie jedoch wie unten vorgehen, wird die Ablaufverfolgung beibehalten und die angefügte Nachricht angezeigt, unabhängig davon, ob die Ausnahme erneut abgefangen wird oder nicht.

try:
  raise ValueError("Original message")
except ValueError as err:
  t, v, tb = sys.exc_info()
  raise t, ValueError(err.message + " Appended Info"), tb

(Ich habe Python 2.7 verwendet, habe es nicht in Python 3 ausprobiert)

0
Zitrax