2013-08-21 9 views
8

Kolega błędnie wpisany ten kod (uproszczony), i zastanawiałem się, dlaczego jego wyjątek nie zaplątuje:Wyjaśnienie "lub" w składni wyjątku, dlaczego jest poprawna składnia i jak działa?

>>> try: 
...  raise ValueError 
... except IndexError or ValueError: 
...  print 'Caught!' 
... 
Traceback (most recent call last): 
    File "<stdin>", line 2, in <module> 
ValueError 

Teraz wiem, że poprawna składnia złapać oba typy wyjątku powinny być except (IndexError, ValueError):, ale dlaczego powyższa ważna składnia? A jak to działa?

Na przykład powyższy kod spowoduje wyświetlenie ValueError i nie zostanie przyłapany. Ale weź ten kod:

>>> try: 
...  raise IndexError 
... except IndexError or ValueError: 
...  print 'Caught!' 
... 
Caught! 

Zostanie złapany IndexError. W jaki sposób oceniany jest model or?

Dzięki za każde światło, które można przelać!

Odpowiedz

12

To dlatego, że IndexError or ValueError jest oceniane na IndexError.

>>> IndexError or ValueError 
<type 'exceptions.IndexError'> 

Operator or zwraca pierwszy wyrażenie zwracające True (W tym przypadku IndexError) lub ostatni wyraz, jeśli żaden z nich są True.
Więc twój oprócz oświadczenia jest rzeczywiście równoważne:

except IndexError: 
+0

Duh !!! Wiedziałem, że ... Po prostu nie zastosowałem tego tutaj. Wiedziałem również, że słowo kluczowe "except" przyjmuje oświadczenia ... więc naprawdę powinienem był to rozgryźć. Dziękuję bardzo! – Ben

+0

@Ben. Nie ma za co :) –

3

wyniku operacji logicznych or i and jest zawsze jednym z argumentów, więc foo or bar oceni do foo jeśli foo jest truthy lub bar jeśli foo jeśli falsy.

W tym przypadku zarówno IndexError i ValueError są truthy tak IndexError or ValueError ocenia się IndexError, a twoja oprócz oświadczenia jest równoznaczne z except IndexError.

Powiązane problemy