2.25. Hantera fel¶
De flesta körtidsproblem i Python visar sig som undantag – ett namngivet, strukturerat sätt att rapportera att något gick fel. ValueError, TypeError, KeyError, OSError, MemoryError är alla exempel; var och en är en klass, och att kasta ett stoppar det aktuella anropet och letar efter en hanterare i den omgivande koden.
2.25.1. try / except¶
Omslut ett kodblock i try för att fånga alla undantag det kastar:
try:
n = int(input_text)
except ValueError:
n = 0
Om konverteringen int(...) misslyckas hoppar kontrollen till except-blocket istället för att fortplanta felet vidare. Om input_text var en giltig heltalssträng hoppas except-blocket över.
Ett enda try kan ha flera except-block, som vart och ett fångar en annan typ av fel:
try:
value = data[key]
except KeyError:
value = None
except TypeError:
value = -1
Python matchar i ordning; det första vars undantagsklass passar hanterar problemet. Att fånga Exception (basklassen för nästan allt) hanterar vilket fel som helst; reservera det för det yttersta lagret av ett program där alternativet är en krasch.
Varning
Ett naket except: (ingen klass efter nyckelordet) fångar också KeyboardInterrupt – undantaget som IDE:n skickar när du trycker på dess stopp-knapp för att avbryta ett körande skript. En loop omsluten av ett naket except: pass sväljer avbrottet och fortsätter köra, vilket inte lämnar något sätt att stoppa skriptet utom en strömcykling.
Föredra except Exception: framför naket except: när du verkligen behöver fånga brett. KeyboardInterrupt ärver från BaseException, inte Exception, så except Exception: lämnar stoppknappen fungerande.
2.25.1.1. Inspektera undantaget¶
För att läsa meddelandet som är kopplat till ett undantag, namnge det med as:
try:
f = open("data.txt")
except OSError as e:
print("could not open file:", e)
Variabeln som binds av as är endast giltig inuti except-blocket.
2.25.2. else och finally¶
Ett try-block har två valfria tillägg.
else körs endast när try slutförts utan att kasta:
try:
value = compute()
except ValueError:
print("bad input")
else:
print("got", value)
Att placera ”vad som ska göras när det fungerade” i else håller try-blocket smalt – endast raden som kan misslyckas hör hemma i try.
finally körs i slutet oavsett vad – vare sig try lyckades, kastade och hanterades, eller kastade och är på väg att fortplantas:
try:
do_work()
finally:
cleanup()
finally körs alltid. else körs endast på vägen utan undantag.¶
För de flesta hämta/frigör-mönster, föredra en kontexthanterare framför ett par av try / finally – resursen sköter sin egen upprensning.
2.25.3. Vanliga inbyggda undantag¶
En kort lista över de undantag du ofta kommer att stöta på:
ValueError– rätt typ, fel värde (bytes([300])– 300 är rätt typ, men ligger utanför det giltiga byteintervallet 0..255).TypeError– helt fel typ (len(42)).IndexError– index bortom slutet av en sekvens.AttributeError– åtkomst av ett attribut som inte finns ("abc".foo).OSError– ett filsystems- eller I/O-fel.MemoryError– slut på heap. På en minnesbegränsad körtid kan detta hända under normal drift – inte bara i patologiska fall.