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ć?

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.

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


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.


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 )


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.