Lo farei così, quindi cambiando il suo tipo foo()
non è necessario 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
Aggiornamento 1
Ecco una leggera modifica che preserva il traceback originale:
...
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
Aggiornamento 2
Per Python 3.x, il codice nel mio primo aggiornamento è sintatticamente errato e l'idea di avere un message
attributo attivo èBaseException
stata ritirata in una modifica a PEP 352 il 16/05/2012 (il mio primo aggiornamento è stato pubblicato il 12-03-2012) . Quindi attualmente, in Python 3.5.2, avresti comunque bisogno di fare qualcosa lungo queste linee per preservare il traceback e non codificare il tipo di eccezione in funzione bar()
. Si noti inoltre che ci sarà la linea:
During handling of the above exception, another exception occurred:
nei messaggi di traceback visualizzati.
# 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')
Aggiornamento 3
Un commentatore ha chiesto se ci fosse un modo che avrebbe funzionato sia in Python 2 e 3. Anche se la risposta potrebbe sembrare di essere "No" a causa delle differenze di sintassi, c'è un modo per aggirare che, utilizzando una funzione di supporto, come reraise()
nel six
add sul modulo. Quindi, se preferisci non utilizzare la libreria per qualche motivo, di seguito è una versione standalone semplificata.
Si noti inoltre che, poiché l'eccezione viene rielaborata all'interno della reraise()
funzione, ciò verrà visualizzato in qualunque traceback generato, ma il risultato finale è quello desiderato.
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
attributo Exception ho trovato questa domanda SO, BaseException.message deprecata in Python 2.6 , che sembra indicare che il suo uso è ora sconsigliato (e perché non è nei documenti).