J'ai une clause try
/finally
dans mon script. Est-il possible d'obtenir le message d'erreur exact à partir de la clause finally
?
Non, à finally
heure sys.exc_info
est tout-Aucun, qu'il y ait eu une exception ou non. Utilisation:
try:
whatever
except:
here sys.exc_info is valid
to re-raise the exception, use a bare `raise`
else:
here you know there was no exception
finally:
and here you can do exception-independent finalization
Le bloc finally
sera exécuté indépendamment du fait qu'une exception ait été levée ou non, donc comme le souligne Josh, vous ne voudrez probablement pas la gérer là-bas.
Si vous avez vraiment besoin de la valeur d'une exception qui a été déclenchée, vous devez intercepter l'exception dans un bloc except
, la gérer correctement ou la relancer, puis utiliser cette valeur dans le bloc finally - dans l'attente qu'il ne puisse jamais avoir été fixé, si aucune exception n'a été levée lors de l'exécution.
import sys
exception_name = exception_value = None
try:
# do stuff
except Exception, e:
exception_name, exception_value = sys.exc_info()[:2]
raise # or don't -- it's up to you
finally:
# do something with exception_name and exception_value
# but remember that they might still be none
En fait, les autres réponses sont un peu vagues. Alors, permettez-moi de le clarifier. Vous pouvez toujours invoquer sys.exc_info () à partir du bloc finally. Cependant, sa sortie variera selon que l'exception a réellement été levée.
import sys
def f(i):
try:
if i == 1:
raise Exception
except Exception as e:
print "except -> " + str(sys.exc_info())
finally:
print "finally -> " + str(sys.exc_info())
f(0)
f(1)
>>>
finally -> (None, None, None)
except -> (<type 'exceptions.Exception'>, Exception(), <traceback object at 0x029438F0>)
finally -> (<type 'exceptions.Exception'>, Exception(), <traceback object at 0x029438F0>)
Ainsi, vous pouvez toujours savoir dans le bloc enfin, si une exception a été déclenchée, s'il s'agit d'une fonction de premier niveau. Mais sys.exc_info () se comportera différemment lorsque la longueur de la pile d'appels dépasse 1, comme illustré dans l'exemple ci-dessous. Pour plus d'informations, reportez-vous à Comment fonctionne sys.exc_info ()?
import sys
def f(i):
try:
if i == 1:
raise Exception
except Exception as e:
print "except -> " + str(sys.exc_info())
finally:
print "finally -> " + str(sys.exc_info())
def f1(i):
if i == 0:
try:
raise Exception('abc')
except Exception as e:
pass
f(i)
f1(0)
f1(1)
>>>
finally -> (<type 'exceptions.Exception'>, Exception('abc',), <traceback object at 0x02A33940>)
except -> (<type 'exceptions.Exception'>, Exception(), <traceback object at 0x02A33990>)
finally -> (<type 'exceptions.Exception'>, Exception(), <traceback object at 0x02A33990>)
J'espère que cela rend les choses un peu plus claires.
Vous voudrez le faire dans la clause except, pas pour finalement.
Voir: http://www.doughellmann.com/articles/Python-Exception-Handling/
Définissez simplement une variable vide pour une éventuelle exception avant le bloc try
except
:
import sys
exception = None
try:
result = 1/0
except ZeroDivisionError as e:
exception = sys.exc_info() # or "e"
finally:
if exception:
print(exception)
else:
print('Everything is fine')
Testé sur Python 3.6