2010-10-14 13 views
29

Rozważmy następujący kod:Co oznacza podwyższenie w Pythonie?

try: 
    raise Exception("a") 
except: 
    try: 
     raise Exception("b") 
    finally: 
     raise 

To podniesie Exception: a. Spodziewałem się, że podniesie on Exception: b (czy muszę wyjaśnić, dlaczego?). Dlaczego ostateczny raise podnosi oryginalny wyjątek, a nie (jak sądziłem) był ostatnim podniesionym wyjątkiem?

+7

Python 3.1 podnosi obie. – kennytm

+1

Ah. Powinienem wspomnieć, że jestem w Pythonie 2.6. – wilhelmtell

+1

Po prostu z ciekawości: kompilator C# na tej samej kombinacji mówi "Błąd: Instrukcja throw bez argumentów nie jest dozwolona w klauzuli finally, która jest zagnieżdżona w najbliższej klauzuli catch enclude" (throw == raise, catch == except). Bez dwuznaczności! – Andrey

Odpowiedz

15

Na python2.6

Chyba, spodziewasz bloku finally być związany z blokiem „spróbować”, gdzie podniesienia wyjątek „B”. Blok finally jest dołączony do pierwszego bloku "try".

Jeśli dodał wyjątkiem bloku w wewnętrznym bloku try, wtedy wreszcie blok podniesie wyjątek B.

try: 
    raise Exception("a") 
except: 
    try: 
    raise Exception("b") 
    except: 
    pass 
    finally: 
    raise 

wyjściowa:

Traceback (most recent call last): 
    File "test.py", line 5, in <module> 
    raise Exception("b") 
Exception: b 

Inną odmianą, która wyjaśnia, co dzieje tutaj

try: 
    raise Exception("a") 
except: 
    try: 
    raise Exception("b") 
    except: 
    raise 

Wyjście:

Traceback (most recent call last): 
    File "test.py", line 7, in <module> 
    raise Exception("b") 
Exception: b 

Jeśli widzisz tutaj, zastępując w końcu bloku z wyjątkiem budzi wyjątek B.

+0

Doszedłem do tego samego wniosku. –

+0

Rzeczywiście to działa! Nigdy bym nie zgadł. Czy to gdzieś dokumentuje? Czy jest to funkcja, czy jest to konieczność wynikająca z problemów gramatycznych? – wilhelmtell

+0

Dlaczego drugi wyjątek nie cienia pierwszego? Żałuję, że Python nie pomyliłby składni, a przynajmniej nie ostrzegł mnie o tym. – wilhelmtell

26

Raise is re-raising the last exception you caught, not the last exception you raised

(Reposted od komentarzy dla jasności)