Håndtere krasj
Vanligvis er krasj av programmet en bra ting, fordi vi ønsker å vite at noe er feil så fort som mulig. Men i noen tilfeller ønsker vi at programmet skal håndtere krasjen selv; dette gjelder egentlig bare når vi vet på forhånd hva slag krasj som kan oppstå, og er ikke et lurt triks å bruke dette for å skyve problemer under teppet.
Generelt vil jeg anbefale å være sparsom med bruken av try og except; hvis det kan håndteres uten på en enkel og grei måte, er det som oftest å foretrekke. Kode som er basert på mye try og except i kontrollflyten er litt mer utfordrende å feilsøke. Samtidig, dersom å bruke try/except sparer mye omstendelig kode kan det være å foretrekke likevel.
Try og except
# Håndtere en krasj
# Prøv å gi programmet noe som ikke er et tall
# Prøv å gi programmet et all som er for stort
# Programmet krasjer ikke selv om brukeren gir ugyldige svar!
animals = ["katt", "hund", "kanin", "hamster", "krokodille"]
print(f"Velg ett tall [0-{len(animals) - 1}]:")
try:
i = int(input())
animal = animals[i]
except:
# Kjøres dersom try-blokken krasjet
print("Ugyldig valg!")
else:
# Kjøres dersom try-blokken gikk bra
print("Gratulerer, du fikk en ny", animal)
print("Nå er programmet ferdig")
Bruk krasjhåndtering med varsomhet. Å bruke mye krasjhåndetring kan gjøre koden din litt vanskeligere å feilsøke.
# FARE!! except håndterer for mange krasjer! Vanskelig å feilsøke!
# Prøv å gi programmet en gyldig tall som input
animals = ["katt", "hund", "kanin", "hamster", "krokodille"]
print(f"Velg ett tall [0-{len(animals) - 1}]:")
try:
i = int(input())
animal = animal[i] # Skrivefeil! Vi VIL krasje her med NameError!
except:
print("Ugyldig valg!") # Oops! Kommer hit selv om input er gyldig
else:
print("Gratulerer, du fikk en ny", animal)
print("Nå er programmet ferdig")
Man bør alltid spesifisere hvilken type krasj man håndeterer.
# Håndere ulike typer feil
animals = ["katt", "hund", "kanin", "hamster", "krokodille"]
print(f"Velg ett tall [0-{len(animals) - 1}]:")
try:
i = int(input())
animal = animals[i]
except ValueError:
print("Ugyldig valg, du må oppgi et tall!")
except IndexError:
print("Tallet du oppgav er ugyldig!")
else:
print("Gratulerer, du fikk en ny", animal)
print("Nå er programmet ferdig")
# NameError blir ikke fanget av except nå,
# så vi oppdager det nå hvis variabeler har feil navn.
Dersom man krasjer inne i en try-blokk med en feil som ikke blir håndtert, kjøres finally likevel
# Håndere ulike typer feil
animals = ["katt", "hund", "kanin", "hamster", "krokodille"]
print(f"Velg ett tall [0-{len(animals) - 1}]:")
try:
i = int(input())
animal = animal[i] # Skrivefeil! Vi krasjer
except ValueError:
print("Ugyldig valg, du må oppgi et tall!")
except IndexError:
print("Tallet du oppgav er ugyldig!")
else:
print("Gratulerer, du fikk en ny", animal)
finally:
# Kjøres selv om det var en krasj i try-blokken som
# ikke ble fanget
print("Vi er ferdig med try/except -blokken nå")
print("Nå er programmet ferdig")
Krasje på egen hånd
Kodeordet raise
brukes for å krasje på egen hånd.
food = input()
if food not in ["salat", "tomat", "agurk", "paprika"]:
raise ValueError(f"Maten '{food}' er ikke akseptabel.")
print("Takk for maten!")
Kan brukes for å gi ekstra informasjon ved krasj
def foo(i, j):
y = j
for x in range(i, j):
try:
y += abs(y/x)
except ZeroDivisionError as err: # err variabel som 'husker' krasjen
# Skriver ut debug-informasjon
print("Divisjon med 0")
print("Lokale variabler: ", locals())
raise err # Kaster samme krasj på nytt
return x
print(foo(-5, 10))