7.4 Instrukcja try

 

Instrukcja try definiuje kod obsługi wyjątków oraz (lub) kod oczyszczający dla grupy instrukcji:

try_stmt  ::=  try_exc_stmt | try_fin_stmt
try_exc_stmt  ::=  "try" ":" suite
    ("except" [expression ["," target]] ":" suite)+
    ["else" ":" suite]
try_fin_stmt  ::=  "try" ":" suite "finally" ":" suite
Pobierz całą gramatykę w postaci tekstowej.

Istnieją dwie formy instrukcji try: try...except oraz try...finally. Nie można ich ze sobą mieszać (choć mogą być w sobie zagnieżdżane).

Zapis try...except określa jeden lub więcej bloków kodu obsługujących wyjątki (wewnątrz klauzul except). Jeśli wewnątrz klauzuli try nie wystąpi żaden wyjątek, nie jest wykonywany zestaw z żadnej z klauzul except. W przeciwnym wypadku rozpoczyna się poszukiwanie kodu obsługującego wyjątek. Polega ono na analizowaniu kolejnych klauzul except do czasu odnalezienia takiej, która pasuje do wyjątku. Jeśli zostanie użyta klauzula except bez zawartego w niej wyrażenia, musi się ona pojawić jako ostatnia i pasuje do każdego wyjątku. Przy pozostałych klauzulach następuje wartościowanie wyrażenia i klauzulę uznaje się za pasującą do wyjątku, jeśli powstały w wyniku wartościowania obiekt jest ,,zgodny'' z wyjątkiem. Zgodność rozumiana jest w ten sposób, że obiekt musi być wartością wyjątku, stanowić klasę bazową dla klasy wyjątku (jeśli wyjątek jest klasą), albo też być krotką zawierającą element, który jest zgodny z wyjątkiem. Zwróćmy uwagę, że pasować muszą do siebie tożsamości obiektów, tzn. wartości wyrażenia i wyjątku muszą opisywać ten sam obiekt, nie zaś dwa obiekty o takiej samej wartości.  

W przypadku, gdy do wyjątku nie pasuje żadna z klauzul except, poszukiwanie kodu obsługi wyjątku jest kontynuowane w kodzie otaczającym instrukcję try i na stosie wywołań.

Jeśli wyjątek wystąpi przy wartościowaniu wyrażenia z nagłówka klauzuli except, poszukiwanie kodu obsługi pierwotnego wyjątku jest przerywane i rozpoczyna się wyszukiwanie kodu obsługi nowego wyjątku w kodzie otaczającym i na stosie wywołań (całość przebiega tak, jakby wyjątek został wygenerowany przez całą instrukcję try).

Jeśli zostanie odnaleziona pasująca do wyjątku klauzula except, jego parametr jest przypisywany celowi określonemu w klauzuli (o ile cel został podany) i następuje wykonanie zestawu z klauzuli. Z każdą z klauzul except musi być związany blok wykonywalny. Jeśli sterowanie osiągnie koniec tego bloku, w zwykły sposób jest przekazywane za całą instrukcję try. (Oznacza to, że jeśli do pewnego wyjątku pasują dwie zagnieżdżone klauzule except, a wyjątek wystąpi w wewnętrznej klauzuli try, to wyjątek nie dotrze do zewnętrznej klauzuli except.)

Przed przystąpieniem do wykonywania zestawu z klauzuli except informacje na temat wyjątku są przypisywane trzem zmiennym z modułu sys : sys.exc_type zawiera obiekt identyfikujący wyjątek; sys.exc_value zawiera parametr wyjątku; sys.exc_traceback zawiera obiekt stanu stosu  (patrz sekcja 3.2), który identyfikuje miejsce w programie, będące źródłem wyjątku. Informacje te są również dostępne za pośrednictwem funkcji sys.exc_info(), która zwraca krotkę (exc_type, exc_value, exc_traceback). Zalecane jest używanie tej właśnie funkcji; bezpośredni dostęp do zmiennych jest mechanizmem przestarzałym, gdyż nie funkcjonuje poprawnie w programach używających wielu wątków. Od Pythona w wersji 1.5 przy powrocie z funkcji, wewnątrz której obsłużono wyjątek zmiennym tym są przywracane ich poprzednie wartości (sprzed wywołania).  

Zestaw z opcjonalnej klauzuli else jest wykonywany, jeśli sterowanie osiągnie koniec zestawu z klauzuli try.7.1 Wyjątki powstałe wewnątrz klauzuli else nie są obsługiwane przez poprzedzające ją klauzule except.  

Postać try...finally instrukcji definiuje kod "oczyszczający" dla grupy instrukcji. W takim wypadku w pierwszej kolejności wykonywany zestaw z klauzuli try. Jeśli nie wystąpi wyjątek, wykonywany jest zestaw z klauzuli finally. Jeśli przy wykonywaniu zestawu z try wyjątek się pojawi, jest on czasowo zapisywany, wykonywany jest zestaw z klauzuli finally i dopiero wówczas ponownie generowany jest zapisany wyjątek. Jeśli wyjątek pojawi się w wyniku wykonania zestawu z klauzuli finally albo też zostanie wewnątrz niego użyta instrukcja return lub break, zapisany wyjątek będzie utracony. Wewnątrz klauzuli finally niedozwolone jest użycie instrukcji continue. (Przyczyna leży w aktualnej implementacji instrukcji, w związku z czym ograniczenie może zostać w przyszłości zniesione). Podczas wykonywania zestawu z klauzuli finally informacje o zapisanym wyjątku nie są dostępne.  

Wykonywanie wewnątrz zestawu z klauzuli try instrukcji return, break lub continue jest dopuszczalne, jednak również w tym przypadku przed przekazaniem sterowania poza instrukcję try wykonywany jest zestaw z klauzuli finally. Używanie continue wewnątrz klauzuli finally jest niedozwolone (jest to ograniczenie implementacji, być może zniknie ono w przyszłości).  

Dodatkowe informacje na temat wyjątków można odnaleźć w sekcji 4.2, zaś informacje na temat generowania wyjątków przy użyciu instrukcji raise -- w sekcji 7.4.



...try.7.1
Aktualnie określenie ,,sterowanie osiągnie koniec zestawu'' wyklucza następujące przypadki: wystąpienie wyjątku, wykonanie instrukcji return, continue lub break.
Zajrzyj do Informacji na temat tej publikacji... aby pomóc w jej rozwoju.