Nie jestem pewien, dlaczego potrzebujemy finally
w try...except...finally
oświadczeniach. Moim zdaniem ten blok kodu
try:
run_code1()
except TypeError:
run_code2()
other_code()
jest to samo z tym przy użyciu finally
:
try:
run_code1()
except TypeError:
run_code2()
finally:
other_code()
Czy coś brakuje?
Możesz użyć
finally
do upewnienia się, że pliki lub zasoby są zamknięte lub zwolnione bez względu na to, czy wystąpi wyjątek, nawet jeśli wyjątek nie zostanie przechwycony. (Lub jeśli nie złapiesz tego konkretnego wyjątku).W tym przykładzie lepiej byłoby użyć
with
instrukcji, ale tego rodzaju struktury można użyć do innych rodzajów zasobów.Kilka lat później napisałem post na blogu o nadużyciach,
finally
które czytelnicy mogą uznać za zabawne.źródło
Nie są równoważne. Wreszcie kod jest uruchamiany bez względu na to, co się jeszcze stanie. Jest to przydatne w przypadku kodu czyszczenia, który musi zostać uruchomiony.
źródło
Finally code is run no matter what else happens
... chyba że istnieje nieskończona pętla. Lub Powercut. Lubos._exit()
. Lub ...os._exit
.Aby dodać do pozostałych odpowiedzi powyżej,
finally
klauzula jest wykonywana bez względu na wszystko, podczas gdyelse
klauzula jest wykonywana tylko wtedy, gdy wyjątek nie został zgłoszony.Na przykład zapis do pliku bez wyjątków spowoduje wyświetlenie następujących danych:
WYNIK:
Jeśli istnieje wyjątek, kod wyświetli następujące informacje (zauważ, że umyślny błąd jest spowodowany utrzymywaniem pliku tylko do odczytu.
WYNIK:
Widzimy, że
finally
klauzula działa niezależnie od wyjątku. Mam nadzieję że to pomoże.źródło
else
to coś. Warto wiedzieć.Bloki kodu nie są równoważne.
finally
Klauzula będzie również działać, jeślirun_code1()
zgłasza wyjątek innego niżTypeError
, lub jeślirun_code2()
zgłasza wyjątek, podczas gdyother_code()
w pierwszej wersji nie będzie działać w takich przypadkach.źródło
W pierwszym przykładzie, co się stanie, jeśli
run_code1()
podniesiony zostanie wyjątek, który nie jestTypeError
? ...other_code()
nie zostanie wykonany.Porównaj to z
finally:
wersją:other_code()
gwarantuje się, że zostanie wykonane niezależnie od zgłoszonego wyjątku.źródło
Jak wyjaśniono w dokumentacji ,
finally
klauzula ma na celu zdefiniowanie działań czyszczących, które należy wykonać w każdych okolicznościach .Przykład:
Jak widać
finally
klauzula jest wykonywana w każdym przypadku.TypeError
Podniesiony przez podzielenie dwa łańcuchy nie są obsługiwane przez zexcept
klauzulą, a zatem ponownie podniesiona pofinally
klauzula została wykonana.W aplikacjach w świecie klauzula „Final” jest przydatna do uwalniania zasobów zewnętrznych (takich jak pliki lub połączenia sieciowe), niezależnie od tego, czy użycie zasobu zakończyło się powodzeniem.
źródło
Idealny przykład jest następujący:
źródło
finally
służy do definiowania „akcji czyszczenia” .finally
Klauzula jest wykonywany w każdym razie przed opuszczeniemtry
stwierdzenie, czy wyjątek (nawet jeśli nie poradzić) doszło, czy nie.Drugi przykład @ Byersa.
źródło
Wreszcie można go również użyć, gdy chcesz uruchomić „opcjonalny” kod przed uruchomieniem kodu do głównej pracy, a ten opcjonalny kod może się nie powieść z różnych powodów.
W poniższym przykładzie nie wiemy dokładnie, jakie wyjątki
store_some_debug_info
mogą zostać zgłoszone.Możemy uruchomić:
Ale większość drobiazgów narzeka na złapanie zbyt niejasnego wyjątku. Ponieważ wybieramy tylko
pass
błędy,except
blok tak naprawdę nie dodaje wartości.Powyższy kod ma taki sam efekt jak pierwszy blok kodu, ale jest bardziej zwięzły.
źródło
Profesjonalne używanie Delphi przez kilka lat nauczyło mnie, jak w końcu zabezpieczyć moje procedury czyszczenia. Delphi prawie wymusza użycie w końcu do wyczyszczenia wszelkich zasobów utworzonych przed blokiem try, aby nie spowodować przecieku pamięci. Tak też działa Java, Python i Ruby.
i zasoby zostaną oczyszczone bez względu na to, co zrobisz między próbą a wreszcie. Ponadto nie zostanie wyczyszczone, jeśli wykonanie nigdy nie dotrze do
try
bloku. (tj.create_resource
sam zgłasza wyjątek) To sprawia, że Twój kod jest „wyjątkowy bezpieczny”.Co do tego, dlaczego tak naprawdę potrzebujesz bloku, nie wszystkie języki tego potrzebują. W C ++, w którym automatycznie wywoływano destruktory, które wymuszają czyszczenie, gdy wyjątek rozwija stos. Myślę, że jest to krok w kierunku czystszego kodu w porównaniu do wypróbowania ... w końcu języków.
źródło
Blok try ma tylko jedną obowiązkową klauzulę: Instrukcja try. Klauzule wyjątkiem, else i wreszcie są opcjonalne i oparte na preferencjach użytkownika.
w końcu: zanim Python opuści instrukcję try, uruchomi kod w bloku last w każdych warunkach, nawet jeśli zakończy działanie programu. Np. Jeśli Python napotkał błąd podczas uruchamiania kodu w bloku wyjątku lub w przeciwnym razie, blok ostatecznie będzie nadal wykonywany przed zatrzymaniem programu.
źródło
Uruchom te kody Python3, aby zobaczyć potrzebę:
PRZYPADEK 1:
PRZYPADEK 2:
Wypróbuj następujące dane za każdym razem:
** Na bardzo wczesnym etapie nauki języka Python.
źródło
Próbowałem uruchomić kod, w którym chciałem czytać arkusze programu Excel. Problem polegał na tym, że jeśli istnieje plik, który nie ma arkusza o nazwie powiedz: SheetSum Nie jestem w stanie przenieść go do lokalizacji błędu !! Kod, który napisałem to:
Podawanie błędu:
Musiałem dodać pełny
try except with finally
blok i powiedzieć, żefinally
muszę zamknąć plik w każdym przypadku, np .:W przeciwnym razie plik nadal pozostaje otwarty w tle.
.. Więcej tutaj
źródło