Je le ferais comme ça, donc changer son type foo()
ne nécessiterait pas de le changer également 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
Mise à jour 1
Voici une légère modification qui préserve le retraçage d'origine:
...
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
Mise à jour 2
Pour Python 3.x, le code de ma première mise à jour est syntaxiquement incorrect et l'idée d'avoir un message
attribut sur a BaseException
été retirée lors d'un changement de PEP 352 le 16/05/2012 (ma première mise à jour a été publiée le 12/03/2012) . Donc actuellement, dans Python 3.5.2 de toute façon, vous devez faire quelque chose dans ce sens pour préserver le traçage et ne pas coder en dur le type d'exception dans function bar()
. Notez également qu'il y aura la ligne:
During handling of the above exception, another exception occurred:
dans les messages de retraçage affichés.
# 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')
Mise à jour 3
Un commentateur a demandé s'il y avait un moyen qui fonctionnerait à la fois dans Python 2 et 3. Bien que la réponse puisse sembler être "Non" en raison des différences de syntaxe, il existe un moyen de contourner cela en utilisant une fonction d'assistance comme reraise()
dans l' six
add- sur le module. Donc, si vous préférez ne pas utiliser la bibliothèque pour une raison quelconque, vous trouverez ci-dessous une version autonome simplifiée.
Notez aussi que puisque l'exception est relancée dans la reraise()
fonction, cela apparaîtra dans tout ce que le retraçage est déclenché, mais le résultat final est ce que vous voulez.
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 Exception, j'ai trouvé cette question SO, BaseException.message obsolète dans Python 2.6 , ce qui semble indiquer que son utilisation est maintenant déconseillée (et pourquoi elle n'est pas dans la documentation).