2010-03-29 12 views
202

Jaka jest różnica między '' i 'jak' w wyjątkiem oświadczenia, np:Python try ... except przecinkiem vs 'jako' w wyjątkiem

try: 
    pass 
except Exception, exception: 
    pass 

oraz:

try: 
    pass 
except Exception as exception: 
    pass 

Czy druga składnia jest legalna w wersji 2.6? Działa w CPython 2.6 na Windowsie, ale tłumacz 2.5 w cygwin narzeka, że ​​jest on nieważny.

Jeśli oba są poprawne w wersji 2.6, z której należy korzystać?

Odpowiedz

229

Ostateczny dokument jest PEP-3110: Catching Exceptions

Podsumowanie:

  • w Pythonie 3.x, używając as jest wymagane przypisać wyjątek zmiennej.
  • W Pythonie 2.6+ użyj składni as, ponieważ jest znacznie mniej niejednoznaczny i zgodny z Pythonem 3.x.
  • W Pythonie 2.5 i wcześniejszych należy używać wersji z przecinkami, ponieważ as nie jest obsługiwany.
+12

Użycie 'as' jest jedynym sposobem przypisania wyjątku do lokalnego w Pythonie 3.x. Ale 'as' nie jest _required_, ponieważ nie musisz go określać, jeśli w ogóle go nie potrzebujesz. – mercator

17

Składnia "as" jest preferowana, jednak jeśli Twój kod musi działać ze starszymi wersjami Pythona (2.6 jest pierwszym, który obsługuje nowe), musisz użyć składni przecinka.

33

Tak, to jest legalne. Używam Python 2.6

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

>>> 
woo hoo 

Aktualizacja: Jest jeszcze jeden powód, aby użyć składni as. Korzystanie z , czyni sprawy bardziej niejednoznacznymi, jak wskazali inni; i oto co robi różnicę. Od wersji Python 2.6 jest multicatch, co pozwala na catch multiple exceptions in one except block. W takiej sytuacji, to jest bardziej wyrazisty i pythonic powiedzieć

except (exception1, exception2) as e 

zamiast powiedzieć

except (exception1, exception2), e 

które nadal pracują

+13

Wersje w języku Python * przed * 2.6 umożliwiają użycie krotki do przechwytywania wielu typów wyjątków. Ale składnia była myląca; użyjesz 'z wyjątkiem NameError, ValueError:' następnie zastanawiasz się, dlaczego wyjątek 'ValueError' nigdy nie został przechwycony. Lub użyte 'except (NameError, e):' i pozostały z 'NameError' dla' 'e''! –

7

Jeśli chcesz obsługiwać wszystkie wersje Python można 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)

+1

Uwaga: tutaj są przypadki narożne, o których należy pamiętać.W Py3, cel 'as' (wraz z resztą informacji o wyjątku) jest niejawnie' deledowany ', gdy tylko wyjdziesz z bloku 'except' (to uniemożliwi niektórym cyklicznym odniesieniom związanym z zapamiętanym tracebackiem opóźnienie zwolnienia pamięć, dopóki cykliczny GC nie zacznie działać). Więc ten ekwiwalentny kod jest nieco mniej równoważny, chyba że użyjesz 'try/finally' w bloku' except', aby upewnić się, że 'del e' jest wykonywane przed wyjściem z bloku' except'. – ShadowRanger

Powiązane problemy