Python essayer… sauf virgule vs «comme» dans sauf

246

Quelle est la différence entre ',' et 'as' dans les instructions except, par exemple:

try:
    pass
except Exception, exception:
    pass

et:

try:
    pass
except Exception as exception:
    pass

La deuxième syntaxe est-elle légale en 2.6? Il fonctionne dans CPython 2.6 sur Windows mais l'interpréteur 2.5 dans cygwin se plaint qu'il n'est pas valide.

S'ils sont tous les deux valides en 2.6, que dois-je utiliser?

Peter Graham
la source

Réponses:

284

Le document définitif est PEP-3110: Attraper les exceptions

Résumé:

  • Dans Python 3.x, l'utilisation asest requise pour affecter une exception à une variable.
  • Dans Python 2.6+, utilisez le as syntaxe, car elle est beaucoup moins ambiguë et compatible avec Python 3.x.
  • Dans Python 2.5 et versions antérieures, utilisez la version virgule, car elle asn'est pas prise en charge.
ambre
la source
16
L'utilisation asest le seul moyen d'attribuer l'exception à un local dans Python 3.x. Mais ce asn'est pas obligatoire , puisque vous n'avez pas à le spécifier si vous n'en avez pas du tout besoin.
mercator
38

Oui c'est légal. J'utilise Python 2.6

try:
    [] + 3
except Exception as x:
    print "woo hoo"

>>> 
woo hoo

Mise à jour : il existe une autre raison d'utiliser la assyntaxe. L'utilisation ,rend les choses beaucoup plus ambiguës, comme d'autres l'ont souligné; et voici ce qui fait la différence. Depuis Python 2.6, il y en a multicatchqui vous permet de capturer plusieurs exceptions dans un seul exceptbloc . Dans une telle situation, c'est plus expressif et pythonique de dire

except (exception1, exception2) as e

plutôt que de dire

except (exception1, exception2), e

qui fonctionnerait toujours

inspecteurG4dget
la source
13
Les versions de Python antérieures à 2.6 vous permettaient également d'utiliser un tuple pour intercepter plusieurs types d'exceptions. Mais la syntaxe était déroutante; vous utiliseriez except NameError, ValueError:alors demandé pourquoi l' ValueErrorexception n'a jamais été interceptée. Ou utilisé except (NameError, e):et se sont retrouvés avec un NameErrorpour 'e'!
Martijn Pieters
17

la syntaxe "as" est la syntaxe préférée à l'avenir, cependant si votre code doit fonctionner avec des versions Python plus anciennes (2.6 est la première à prendre en charge la nouvelle), vous devrez utiliser la syntaxe virgule.

Alex Gaynor
la source
9

Si vous souhaitez prendre en charge toutes les versions de python, vous pouvez utiliser la sys.exc_info()fonction comme ceci:

try:
    a = 1/'0'
except (ZeroDivisionError, TypeError):
    e = sys.exc_info()[1]
    print(e.args[0])

(source: http://python3porting.com/noconv.html )

pthomaid
la source
2
Remarque: Il y a quelques cas d'angle à connaître. Dans Py3, la ascible (ainsi que le reste des informations d'exception) est implicitement éditée deldès que vous quittez le exceptbloc (cela empêche certaines références cycliques impliquées dans le traçage stocké de retarder la libération de la mémoire jusqu'à ce que le GC cyclique se mette à fonctionner) ). Donc, ce code équivalent est légèrement moins équivalent, sauf si vous utilisez un try/finallydans le exceptbloc pour vous assurer qu'il del eest effectué avant de quitter le exceptbloc.
ShadowRanger
0

Depuis Python 3.7 (pas sûr des autres versions) la syntaxe 'virgule' n'est plus supportée:

Fichier source exception_comma.py:

try:
    result = 1/0
except Exception, e:
    print("An error occurred")
    exit(1)

exit(0)
  • $ python --version --> Python 2.7.10
$ python exception_comma.py
An error occurred
  • $ python3 --version --> Python 3.7.2
$ python3 exception_comma.py
  File "exception_comma.py", line 3
    except Exception, e:
                    ^
SyntaxError: invalid syntax
Marcello Romani
la source