Python próbuje… z wyjątkiem przecinka vs „as” w wyjątkiem

246

Jaka jest różnica między „,” a „jak” w instrukcjach z wyjątkiem, np .:

try:
    pass
except Exception, exception:
    pass

i:

try:
    pass
except Exception as exception:
    pass

Czy druga składnia jest legalna w wersji 2.6? Działa w CPython 2.6 w systemie Windows, ale interpreter 2.5 w cygwin skarży się, że jest nieprawidłowy.

Jeśli oba są ważne w 2.6, którego powinienem użyć?

Peter Graham
źródło

Odpowiedzi:

284

Ostateczny dokument to PEP-3110: Łapanie wyjątków

Podsumowanie:

  • W Pythonie 3.x użycie asjest wymagane do przypisania wyjątku do zmiennej.
  • W Pythonie 2.6+ użyj asskładni, ponieważ jest ona mniej jednoznaczna i kompatybilna z Pythonem 3.x.
  • W Python 2.5 i wcześniejszych wersjach używaj przecinków, ponieważ asnie są obsługiwane.
Bursztyn
źródło
16
Użycie asjest jedynym sposobem przypisania wyjątku do lokalnego w Pythonie 3.x. Ale asnie jest to wymagane , ponieważ nie musisz go określać, jeśli w ogóle go nie potrzebujesz.
mercator,
38

Tak, to legalne. Korzystam z języka Python 2.6

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

>>> 
woo hoo

Aktualizacja : Istnieje inny powód, aby użyć asskładni. Używanie ,czyni rzeczy o wiele bardziej niejednoznacznymi, jak zauważyli inni; i oto, co robi różnicę. Począwszy od wersji Python 2.6 istnieje multicatchmożliwość przechwycenia wielu wyjątków w jednym exceptbloku . W takiej sytuacji jest to bardziej wyraziste i pytoniczne

except (exception1, exception2) as e

zamiast powiedzieć

except (exception1, exception2), e

co nadal działałoby

inspectorG4dget
źródło
13
Wersje Python wcześniejsze niż 2.6 pozwalały na użycie krotki do przechwytywania wielu typów wyjątków. Ale składnia była myląca; użyłbyś except NameError, ValueError:wtedy, zastanawiałeś się, dlaczego ValueErrorwyjątek nigdy nie został złapany. Lub wykorzystywane except (NameError, e):i zostały pozostawione z NameErrorza 'e'!
Martijn Pieters
17

preferowana jest składnia „as”, jednak jeśli twój kod musi współpracować ze starszymi wersjami języka Python (2.6 obsługuje pierwszą wersję), musisz użyć składni przecinków.

Alex Gaynor
źródło
9

Jeśli chcesz obsługiwać wszystkie wersje Pythona, możesz użyć sys.exc_info()funkcji w następujący sposób:

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

(źródło: http://python3porting.com/noconv.html )

pthomaid
źródło
2
Uwaga: Istnieje kilka przypadków narożnych, o których należy pamiętać. W Py3 ascel (wraz z resztą informacji o wyjątku) jest domyślnie edytowany delnatychmiast po wyjściu z exceptbloku (zapobiega to opóźnieniu zwolnienia pamięci przez niektóre cykliczne odwołania związane z przechowywanym śledzeniem), dopóki cykliczny GC nie zacznie działać ). Więc ten równoważny kod jest nieco mniej równoważny, chyba że użyjesz try/finallywewnątrz exceptbloku, aby upewnić się, że del ejest wykonywany przed wyjściem z exceptbloku.
ShadowRanger
0

Od wersji Python 3.7 (nie jestem pewien co do innych wersji) składnia „przecinków” nie jest już obsługiwana:

Plik źródłowy 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
źródło