2012-06-22 14 views
53

To jest kod, który zachowuje się szczególnie. Jest to uproszczona wersja zachowania, które napisałem. To nadal będzie świadczyć o dziwnym zachowaniu i miałem kilka konkretnych pytań na temat tego, dlaczego tak się dzieje.Weird Try-Except-Else-Ostatnie zachowanie z instrukcjami Return

Używam Python 2.6.6 na Windows 7.

def demo1(): 
    try: 
     raise RuntimeError,"To Force Issue" 
    except: 
     return 1 
    else: 
     return 2 
    finally: 
     return 3 

def demo2(): 
    try: 
     try: 
      raise RuntimeError,"To Force Issue" 
     except: 
      return 1 
     else: 
      return 2 
     finally: 
      return 3 
    except: 
     print 4 
    else: 
     print 5 
    finally: 
     print 6 

if __name__ == "__main__": 
    print "*** DEMO ONE ***" 
    print demo1() 
    print "****************" 
    print 
    print "*** DEMO TWO ***" 
    print demo2() 
    print "****************" 

Po uruchomieniu tego skryptu, zostanie wydrukowana:

*** DEMO ONE *** 
3 
**************** 

*** DEMO TWO *** 
6 
3 
**************** 

Dlaczego demo jeden powrocie 3 zamiast 1? Dlaczego demo dwa drukowanie 6 zamiast drukowania 6 w/4 lub 5?

Dzięki za pomoc.

Odpowiedz

80

Ponieważ finally stwierdzenia są gwarantowana do wykonania (dobrze, zakładając żadnej przerwy w dostawie prądu lub czegokolwiek poza kontrolą Pythona). Oznacza to, że zanim funkcja może powrócić, musi uruchomić blok finally, który zwraca inną wartość.

Python docs stan:

Podczas powrotu, złamać lub kontynuować oświadczenie jest wykonywany w apartamencie try try ... finally, klauzula finally jest również wykonywane „po drodze”. Instrukcja continue jest niezgodna z klauzulą ​​finally. (Powodem jest problem z bieżącą implementacją - to ograniczenie może zostać zniesione w przyszłości).

To oznacza, że ​​przy próbie powrotu, blok finally nazywa, zwracając jego wartość, aniżeli ten, który byś miał.

+1

dlaczego nie drukuje 5 w drugim przykładzie? to nadal nie jest dobrze wyjaśnione, myślę. odpowiedź zwrotna jest dobrze odpowiedziana, ale dlaczego 5 w drugim przykładzie nie drukuje –

+4

oh myślę, że znalazłem to, że powrót w początkowej próbie powoduje, że przeskoczył natychmiast na zewnątrz ostatecznie –

+2

Dokładnie, ponieważ 'w końcu' blokuje ** zawsze ** biegać. –

1

wykonanie zlecenia jest: blok

  1. try wszystko zakończy normalnie -> w końcu zablokować -> funkcja kończy
  2. bloku try biegać i dostać się do wyjątków A -> w końcu zablokować -> funkcja kończy
  3. spróbuj zrobić blok wartości zwracanej i wywołać zwrot -> w końcu zablokować -> podręczne wartości zwracanej -> funkcja kończy

więc każdy zwrot w bloku finally zakończy czynności z wyprzedzeniem.

+0

Możesz użyć formatu listy dla swojej odpowiedzi. – gsamaras