Python 3/Virheidenhallinta

Virheitä tapahtuu usein ohjelmissa. Ongelmana saattaa esimerkiksi olla se, että käytäjä antaa vääränlaisen syötteen. Virheitä voi hallita try-except- ja try-finally-virheenhallintarakenteilla.

Esimerkki ohjelmasta, jossa tapahtuu virhe.

#!/usr/bin/python3
# -*- coding: utf-8 -*-

numero = "Peikko"

print (numero+1)
Tuloste
Traceback (most recent call last):
  File "./test.py", line 6, in <module>
    print (numero+1)
TypeError: cannot concatenate 'str' and 'int' objects

Ohjelma kaatuu virheeseen. numero muuttuja olisi voinnut sisältää esimerkiksi käyttäjän antaman syöteen, jossa käyttäjän olisi pitänyt antaa luku, mutta käyttäjä antoikin syötteeksi tekstiä.

try-except-virheenhallintarakenne muokkaa

try-except-virheenhallintarakenteessa pitää olla yksi try-osio ja vähintää yksi except-osio. try-except-virheenhallintarakenne ei lopeta ohjelmaa vaan ohjelman suorittaminen jatkuu virheenhallintarakenteen jälkeen. Esimerkki try-except-virheenhallintarakenteesta, jossa kerrotaan virheestä.

#!/usr/bin/python3
# -*- coding: utf-8 -*-

numero = "Peikko"

# try-osio
try:
    print(numero+1)

# except-osio suoritetaan jos try-osiossa tapahtuu virhetilanne
except:
    print("Tapahtui virhe")
Tuloste
Tapahtui virhe

Tämä ei vielä kerro miksi virhe tapahtui. Jos except-osiossa ei määritetä virhetilanteita, joissa se pitää suorittaa niin se suoritetaan kaikissa try-osion virhetilanteissa.

Esimerkki, jossa määritetään virhetilanne.

#!/usr/bin/python3
# -*- coding: utf-8 -*-

numero = "Peikko"

# try-osio
try:
    print(numero+1)

# suoritetaan jos try-osiossa tapahtuu TypeError-virhe
except TypeError:
    print("Virheellinen syöte")

# Suoritetaan kaikissa muissa virhetilanteissa
except:
    print("Tapahtui virhe")

print("Ohjelma suorittaminen jatkuu")
Tuloste
Virheellinen syöte
Ohjelma suorittaminen jatkuu

Tämän virheen tuloste kertoo jo paljon enemmän. Virheilmoituksen tilalla voisi esimerkiksi pyytää käyttäjää antamaan syötteen uudelleen. Esimerkistä näkyy myös se, että ohjelman suorittaminen jatkuu vaikka tapahtuisi virhe.

try-except-else-virheenhallintarakenne muokkaa

Esimerkki try-except-else-virheenhallintarakenteesta.

#!/usr/bin/env python3

syote = input('Anna luku: ')

# try-osio
try:
    luku = int(syote)
    tulos = luku ** 2

# suoritetaan jos try-osiossa tapahtuu TypeError-virhe
except TypeError:
    print("Virheellinen syöte")

# Suoritetaan vain jos try-osiossa ei tapahtunut virhettä
else:
    print("Tulos:", tulos)
Tuloste
Anna luku: 

Syötetään ”3”.

Tulos: 9

else-osio suoritetaan vain silloi kun try-osiossa ei tapahdu virhettä.

try-finally-virheenhallintarakenne muokkaa

try-finally-virheenhallintarakenteen tarkoitus on sulkea ohjelma hallitusti virheen sattuessa. try-finally-virheenhallintarakenteessa virheen tapahtuessa try-osiossa suoritetaan finally-osio, jonka jälkeen ohjelman suorittaminen lopetetaan. Finally-osio suoritetaan myös kun virhettä ei satu. Finally-osiossa voi tehdä tehtävät, jotka ovat yhteisiä virhetilanteelle ja onnistuneelle suoritukselle, kuten esimerkiksi sulkea tiedosto, että se ei jää auki virheen sattuessa.

Esimerkki try-finally-virheenhallintarakenteesta

#!/usr/bin/env python3

numero = "Peikko"
print("Avataan tiedosto")
tiedosto = open("numerot.txt", "w")

# try-osio
try:
    tiedosto.write(numero + 1)

# finally-osio suoritetaan joka tapauksessa tapahtui virhe tai ei
finally:
    print("Suljetaan tiedosto")
    tiedosto.close()

# Viesti "Laskeminen onnistui" voidaan tulostaa tässä kohtaa, koska sitä ei tulosteta virheen tapahtuessa
print("Tallentaminen onnistui")
Tuloste
Avataan tiedosto
Suljetaan tiedosto
Traceback (most recent call last):
  File "tryfinally.py", line 9, in <module>
    print(numero+1)
TypeError: can only concatenate str (not "int") to str

Yleisimmät virheet muokkaa

Pythonissa on paljon erillaisia virhetyyppejä.

Taulukko yleisimmistä virheluokista

Virheluokka Kuvaus
Exception Yleisluokka
TypeError Virheellinen muuttujan tyyppi
ValueError Virheellinen muuttujan arvo