W trakcie wykonywania skryptów, często okazuje się, że natrafiamy na błędy. W takiej sytuacji skrypt kończy swoje działanie, a istnieją sytuacje, w których nie jest to konieczne np. praca na nieistniejącym pliku.
I tutaj z pomocą przychodzą nam wyjątki, które wyświetlają stosowną informację dla użytkownika w przypadku błędu i umożliwiają kontynuację pracy skryptu.
Schemat działania jest standardowy, najpierw próbujemy wykonać kod, a jeżeli coś pójdzie nie tak, to wykonujemy inny.
try: wypróbuj coś co może wywołać błąd
except: wykonaj to jeżeli trafił się błąd
else: wykonaj to jeżeli nie było błędu
finally: wykonaj to nie ważne co się stanie
Błędy jakie możemy napotkać to m.in
FileNotFound
with open("file.txt") as file: file.read()KeyError
some_dictionary = {"key" : "value"}value = some_dictionary["non_exist_key"]IndexError
some_list = ["PHP", "Python", "JAVA"]#ang = some_list[3]TypeError
text = "abc"print(text+5)Zastosowanie przechwytywania błędów
try:
with open("file.txt") as file:
file.read()
except:
with open("file.txt", "w") as file:
file.write("something")
Jednak nie powinniśmy stosować czystego except – powinniśmy wskazać jaki rodzaj błędu chcemy przechwycić, inaczej wszystkie napotkane problemy zostaną rozwiązane w jeden sposób
#np. jeżeli zastosujemy poniższy przykład nie otrzymamy żadnego błędu
try:
with open("file.txt") as file:
file.read()
a_dictionary = {"key":"value"}
print(a_dictionary["jdshbck"])
except:
with open("file.txt", "w") as file:
file.write("something")
Zależy nam na przechwytywaniu konkretnych błędów
try:
with open("file.txt") as file:
file.read()
a_dictionary = {"key":"value"}
print(a_dictionary["jdshbck"])
except FileNotFoundError:
with open("file.txt", "w") as file:
file.write("something")
Po uruchomieniu powyższego kodu zobaczymy błąd: KeyError: 'jdshbck’
naprawmy tą sytuację
try:
with open("file.txt") as file:
file.read()
a_dictionary = {"key":"value"}
print(a_dictionary["jdshbck"])
except FileNotFoundError:
with open("file.txt", "w") as file:
file.write("something")
except KeyError:
print("Klucz nie zostal znaleziony")
możemy przypisać błąd do zmiennej
try:
with open("file.txt") as file:
file.read()
a_dictionary = {"key":"value"}
print(a_dictionary["jdshbck"])
except FileNotFoundError:
with open("file.txt", "w") as file:
file.write("something")
except KeyError as error_message:
print(f"Klucz {error_message} nie zostal znaleziony")
a teraz dodamy blok else, który wykona się jeżeli w bloku try nie będzie błędów
try:
with open("file.txt") as file:
content = file.read()
a_dictionary = {"key":"value"}
print(a_dictionary["key"])
except FileNotFoundError:
with open("file.txt", "w") as file:
file.write("something")
except KeyError as error_message:
print(f"Klucz {error_message} nie zostal znaleziony")
else: #blok else nie wykona się jeżeli wystąpi którykolwiek z powyższych błędów
print(content)
a teraz dodamy blok, który wykona się bez względu na to czy będą błędy, czy też nie
try:
with open("file.txt") as file:
content = file.read()
a_dictionary = {"key":"value"}
print(a_dictionary["jbfvd"])
except FileNotFoundError:
with open("file.txt", "w") as file:
file.write("something")
except KeyError as error_message:
print(f"Klucz {error_message} nie zostal znaleziony")
else:
print(content)
finally:
print("Jest KeyError, a ja i tak działam")
inne przykłady
print(1/0)
try:
print("Próbujemy dzielić przez 0")
wynik = 1/0 # to wywoła błąd ZeroDivisionError: division by zero
print("to się nie wykona")
except Exception:
print("Wyjątek został przechwycony")
wynik = 0
print(wynik)
praktyczny przykład – co jeżeli użytkownik wpisze wartość jakiej nie oczekujemy (np literę zamiast liczby)
num = input("Podaj liczbę int")
try:
num = int(num)
except Exception:
num = "To nie jest integer"
print(num)
wyświetlimy rodzaj błędu
num = input("Podaj liczbę int: ")
try:
num = int(num)
except ValueError:
print(num, "niepoprawny format liczby")
except Exception as e:
print("Wyjątek został przechwycony: ", type(e))
num = "To nie jest integer"
print(num)
Własne wyjątki
pomimo poprawnego wykonania kodu możemy narzucić wywołanie błędu np:
try:
with open("file.txt") as file:
content = file.read()
a_dictionary = {"key":"value"}
print(a_dictionary["key"])
except FileNotFoundError:
with open("file.txt", "w") as file:
file.write("something")
except KeyError as error_message:
print(f"Klucz {error_message} nie zostal znaleziony")
else:
print(content)
finally:
raise TypeError("A i tak masz błąd haha")
Kiedy możemy zastosować powyższe?
Wyobraźcie sobie, że macie kalkulator BMI i ktoś wpisze wzrost powyżej 3m… troszkę wysoki ten ludzik, możemy wtedy narzucić np. ValueError
Wykonaj takie ćwiczenie – stwórz kalkulator BMI i narzuć błąd ValueError
height = float(input("Height: "))
weight = int(input("Weight: "))
if height>3:
raise ValueError("Wzrost człowieka raczej nie jest większy niż 3m")
bmi = weight / height ** 2
print(bmi)
Zadanie:
Przechwyć wszystkie błędy w poniższym kodzie
fruits = ["Apple", "Pear", "Orange"]
def make_pie(index):
fruit = fruits[index]
print(fruit + " pie")
make_pie(4)
Rozwiązanie
fruits = ["Apple", "Pear", "Orange"]
def make_pie(index):
try:
fruit = fruits[index-1]
except IndexError:
print(f"Nie mamy takiego składnika, wybierz maksymalnie {len(fruits)}")
else:
print(fruit + " pie")
make_pie(3)
Zdanie:
Zapobiegnij błędom
facebook_posts = [
{'Likes': 21, 'Comments': 2},
{'Likes': 13, 'Comments': 2, 'Shares': 1},
{'Likes': 33, 'Comments': 8, 'Shares': 3},
{'Comments': 4, 'Shares': 2},
{'Comments': 1, 'Shares': 1},
{'Likes': 19, 'Comments': 3}
]
total_likes = 0
for post in facebook_posts:
total_likes = total_likes + post['Likes']
Rozwiązanie
facebook_posts = [
{'Likes': 21, 'Comments': 2},
{'Likes': 13, 'Comments': 2, 'Shares': 1},
{'Likes': 33, 'Comments': 8, 'Shares': 3},
{'Comments': 4, 'Shares': 2},
{'Comments': 1, 'Shares': 1},
{'Likes': 19, 'Comments': 3}
]
total_likes = 0
for post in facebook_posts:
try:
total_likes = total_likes + post['Likes']
except KeyError:
pass
else:
print(total_likes)