Ich würde es so machen, so dass das Ändern des Typs foo()
nicht auch das Ändern des Typs erfordert bar()
.
def foo():
try:
raise IOError('Stuff')
except:
raise
def bar(arg1):
try:
foo()
except Exception as e:
raise type(e)(e.message + ' happens at %s' % arg1)
bar('arg1')
Traceback (most recent call last):
File "test.py", line 13, in <module>
bar('arg1')
File "test.py", line 11, in bar
raise type(e)(e.message + ' happens at %s' % arg1)
IOError: Stuff happens at arg1
Update 1
Hier ist eine geringfügige Änderung, die den ursprünglichen Traceback beibehält:
...
def bar(arg1):
try:
foo()
except Exception as e:
import sys
raise type(e), type(e)(e.message +
' happens at %s' % arg1), sys.exc_info()[2]
bar('arg1')
Traceback (most recent call last):
File "test.py", line 16, in <module>
bar('arg1')
File "test.py", line 11, in bar
foo()
File "test.py", line 5, in foo
raise IOError('Stuff')
IOError: Stuff happens at arg1
Update 2
Für Python 3.x ist der Code in meinem ersten Update syntaktisch falsch und die Idee, ein message
Attribut zu haben, BaseException
wurde bei einer Änderung von PEP 352 am 16.05.2012 zurückgezogen (mein erstes Update wurde am 12.03.2012 veröffentlicht). . Derzeit müssen Sie in Python 3.5.2 ohnehin etwas in diese Richtung tun, um den Traceback beizubehalten und den Typ der Ausnahme in der Funktion nicht fest zu codieren bar()
. Beachten Sie auch, dass es die Zeile geben wird:
During handling of the above exception, another exception occurred:
in den Traceback-Meldungen angezeigt.
# for Python 3.x
...
def bar(arg1):
try:
foo()
except Exception as e:
import sys
raise type(e)(str(e) +
' happens at %s' % arg1).with_traceback(sys.exc_info()[2])
bar('arg1')
Update 3
Ein Kommentator fragte, ob es einen Weg gäbe, der sowohl in Python 2 als auch in Python 3 funktionieren würde. Obwohl die Antwort aufgrund der Syntaxunterschiede "Nein" zu sein scheint, gibt es einen Weg, dies zu umgehen , indem eine Hilfsfunktion wie reraise()
im six
Add-In verwendet wird. auf Modul. Wenn Sie die Bibliothek aus irgendeinem Grund lieber nicht verwenden möchten, finden Sie unten eine vereinfachte Standalone-Version.
Beachten Sie auch, dass, da die Ausnahme innerhalb der reraise()
Funktion erneut ausgelöst wird, diese in jedem Traceback angezeigt wird, aber das Endergebnis das ist, was Sie wollen.
import sys
if sys.version_info.major < 3: # Python 2?
# Using exec avoids a SyntaxError in Python 3.
exec("""def reraise(exc_type, exc_value, exc_traceback=None):
raise exc_type, exc_value, exc_traceback""")
else:
def reraise(exc_type, exc_value, exc_traceback=None):
if exc_value is None:
exc_value = exc_type()
if exc_value.__traceback__ is not exc_traceback:
raise exc_value.with_traceback(exc_traceback)
raise exc_value
def foo():
try:
raise IOError('Stuff')
except:
raise
def bar(arg1):
try:
foo()
except Exception as e:
reraise(type(e), type(e)(str(e) +
' happens at %s' % arg1), sys.exc_info()[2])
bar('arg1')
message
Attribut habe ich diese SO-Frage gefunden: BaseException.message ist in Python 2.6 veraltet , was darauf hindeutet, dass die Verwendung jetzt nicht empfohlen wird (und warum sie nicht in den Dokumenten enthalten ist).