Lo haría así, así que cambiar su tipo foo()
no requerirá también cambiarlo 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
Actualización 1
Aquí hay una ligera modificación que conserva el rastreo original:
...
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
Actualización 2
Para Python 3.x, el código en mi primera actualización es sintácticamente incorrecto y la idea de tener un message
atributo activadoBaseException
se retractó en un cambio a PEP 352 el 16/05/2012 (mi primera actualización se publicó el 12/03/2012) . Entonces, actualmente, en Python 3.5.2 de todos modos, necesitaría hacer algo en este sentido para preservar el rastreo y no codificar el tipo de excepción en la función bar()
. También tenga en cuenta que habrá la línea:
During handling of the above exception, another exception occurred:
en los mensajes de rastreo que se muestran.
# 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')
Actualización 3
Un comentarista preguntó si había una manera que funcione tanto en Python 2 y 3. Aunque la respuesta podría parecer que es "No", debido a las diferencias de sintaxis, no es una forma de evitar que mediante el uso de una función de ayuda al igual que reraise()
en el six
Agregar- en el módulo Entonces, si prefiere no usar la biblioteca por alguna razón, a continuación se muestra una versión independiente simplificada.
Tenga en cuenta también que, dado que la excepción se vuelve a generar dentro de la reraise()
función, aparecerá en cualquier rastreo que se genere, pero el resultado final es lo que desea.
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
atributo Exception , encontré esta pregunta SO, BaseException.message en desuso en Python 2.6 , que parece indicar que su uso ahora está desaconsejado (y por qué no está en los documentos).