Les deux extraits de code suivants font la même chose. Ils interceptent chaque exception et exécutent le code dans le bloc except:
Extrait 1 -
try:
#some code that may throw an exception
except:
#exception handling code
Extrait 2 -
try:
#some code that may throw an exception
except Exception as e:
#exception handling code
Quelle est exactement la différence dans les deux constructions?
Dans la seconde, vous pouvez accéder aux attributs de l'objet exception:
>>> def catch():
... try:
... asd()
... except Exception as e:
... print e.message, e.args
...
>>> catch()
global name 'asd' is not defined ("global name 'asd' is not defined",)
Mais il ne prend pas BaseException
ou les exceptions qui sortent du système SystemExit
, KeyboardInterrupt
et GeneratorExit
:
>>> def catch():
... try:
... raise BaseException()
... except Exception as e:
... print e.message, e.args
...
>>> catch()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in catch
BaseException
Ce qui est nu excepté:
>>> def catch():
... try:
... raise BaseException()
... except:
... pass
...
>>> catch()
>>>
Voir la section Exceptions intégrées de la documentation et la section Erreurs et exceptions du didacticiel pour plus d'informations.
except:
accepte tous exceptions, alors que
except Exception as e:
accepte uniquement les exceptions que vous êtes destiné à intercepter.
Voici un exemple de ce que vous n'êtes pas censé attraper:
>>> try:
... input()
... except:
... pass
...
>>> try:
... input()
... except Exception as e:
... pass
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
KeyboardInterrupt
Le premier a réduit au silence le KeyboardInterrupt
!
Voici une liste rapide:
issubclass(BaseException, BaseException)
#>>> True
issubclass(BaseException, Exception)
#>>> False
issubclass(KeyboardInterrupt, BaseException)
#>>> True
issubclass(KeyboardInterrupt, Exception)
#>>> False
issubclass(SystemExit, BaseException)
#>>> True
issubclass(SystemExit, Exception)
#>>> False
Si vous voulez attraper l'un de ceux-là, mieux vaut le faire
except BaseException:
pour souligner que vous savez ce que vous faites.
Toutes les exceptions proviennent de BaseException
, et celles que vous êtes censé prendre au jour le jour (celles qui seront lancées pour le programmeur) hérite aussi de Exception
.
Il existe des différences, à quelques exceptions près, par exemple KeyboardInterrupt.
Lecture PEP8 :
Une clause bare except: intercepte les exceptions SystemExit et KeyboardInterrupt, ce qui rend plus difficile l'interruption d'un programme avec Control-C et peut dissimuler d'autres problèmes. Si vous voulez intercepter toutes les exceptions signalant des erreurs de programme, utilisez except Exception: (nu sauf équivaut à excepter BaseException :).
La seconde forme vous donne une variable (nommée en fonction de la clause as
, dans votre exemple e
) dans la portée du bloc except
avec l’objet exception qui lui est lié afin que vous puissiez utiliser le informations dans l’exception (type, message, trace de pile, etc.) pour gérer l’exception dans un manoir plus adapté.