Vead¶
Koodi käivitamisel võivad tekkida erindid (ingl. keeles Exception), mis võivad programmi töö peatada. Peatamisel teavitatakse kasutajat veast, kirjeldatakse mõjutatud rida ja veatüüpi. On oluline osata neid lugeda ja mõista.
Mõningate vigade puhul oskab Python öelda päris täpselt, et mis läks valesti, kuid sellegipoolest ei parandata ühtegi viga arendaja eest. Nii on see kõikides programmeerimiskeeltes, kuna interpretaator (ega ka kompilaator) ei tohi kunagi eeldada, et mida temalt soovitakse. Arvuti teeb täpselt seda, mida sa talle ütled.
Selline teoreetiline maailm, kus Python võib arendaja koodi omavoliliselt „parandada“ võib esile tuua raskemini lahendatava mure - programm töötab, kuid tulemus on vale!
Vigade ehk erindite kinnipüüdmisest saab lugeda siin: Erindid (Exceptions).
Järgnev video tutvustab vigade mõistmist ja nende lahendamist:
`SyntaxError`
Kõige lihtsam ja võib-olla tihedamini esinev viga on SyntaxError
, mis näitab, et kuskil koodis on süntaksi viga.
Rahvakeeli võib öelda, et tegemist on justkui kirjaveaga lauses.
# An example of a classic syntax error: the closing quotation mark is missing.
print("Hello world!)
Üleval oleva koodi käivitamise proovimisel saame süntaksivea, mis näitab meile vea kohta ja annab kaasa täpsustava sõnumi.
Traceback (most recent call last):
File "<path to the file>", line 3
print("Hello world!)
^
SyntaxError: EOL while scanning string literal
Process finished with exit code 1
`IndentationError`
Python’is taanded on ka süntaksi osa ja nende vale kasutamine põhjustab kompileerimise vigu.
def func(a, b):
return a + b # --> IndentationError
Traceback (most recent call last):
File "<path to the file>", line 3 # Number of line where the error occurred
return a + b
^
IndentationError: expected an indented block
Process finished with exit code 1
Eelnev veateade kirjeldab, et esiletoodud rida asub ootamatul taandel.
`IndexError`
Tekib siis, kui indeks, mille järgi proovitakse saada elementi listist, ei ole korrektne.
some_list = ["Errors", "are", "sometimes", "better", "than", "no", "errors"]
print(some_list.__len__()) # --> 7
# There is no element in the list with such index
print(some_list[7]) # --> IndexError: list index out of range
Traceback (most recent call last):
File "<path to the file>", line 4, in <module>
print(some_list[7])
IndexError: list index out of range
`KeyError`
Sarnane IndexError
veale, kuid siin puhul üritatakse otsida sõnastikust võtit, mida sõnastikus ei esine.
grades = {
"english": 4,
"math": 2,
"physics": 3
}
print(grades["geography"]) # --> KeyError
Traceback (most recent call last):
File "test.py", line 7, in <module>
print(grades["geography"])
KeyError: 'geography'
Veateade kirjeldab rida, kus antud viga ilmnes, ning toob välja ka võtme, mida prooviti. Sõnastike puhul on muidu olemas viis, kuidas vältida vea ilmnemist juhul, kui võtit ei ole.
grades = {
"english": 4,
"math": 2,
"physics": 3
}
print(grades.get("geography")) # --> None
Antud juhul on tulemuseks None
. Küll oleks mõistlik seda varianti kasutada ainult siis, kui
mitte-leidmine on ettenähtud ning sinu ülejäänud kood oskab arvestada None
tüüpi vastusega.
`NameError`
Tekib siis, kui proovitakse kasutada muutujat, mis ei olnud kunagi deklareeritud.
print(undeclared_variable + 10) # --> NameError
Traceback (most recent call last):
File "<path to the file>", line 2, in <module>
print(undeclared_variable + 10)
NameError: name 'undeclared_variable' is not defined
`TypeError`
TypeError
tähendab, kui üritatakse teha tegevusi kahe erineva tüübi vahel, mis kuidagi kokku ei käi.
Tekib näiteks siis, kui proovitakse teha kahe muutuja liitmist, kus üks liidetavatest on sõne ja teine näiteks täisarv (int).
var = "10"
print(var + 10) # --> TypeError: must be str, not int (cannot concatenate objects)
Traceback (most recent call last):
File "<path to the file>", line 5, in <module>
print(var + 10)
TypeError: must be str, not int
Veateadete mõistmine
Veateade annab meile järgmist informatsiooni:
kus tekkib viga (koodilõik ja rea number)
milline viga tekkis (
IndexError
vms)täpsustav sõnum (näiteks string’ide liitmise korral, et üks liidetavatest ei ole string)
Olukord võib olla keerulisem juhul, kui näiteks meie kutsume funktsiooni, mis omakorda kutsub teise funktsiooni, kus tekkib viga. Vaatame, mis me saame väljundiks sellel juhul.
Olgu meil on selline kood
def third(a):
print(int(a)) # Attempt to convert string <The output is called 'Stack Trace'> to int and print it out
def second(a, b):
c = a + b
print(c) # --> The output is called 'Stack Trace'
# Calling the third function
third(c)
def first():
# Calling the second function
second("The output is called ", "'Stack Trace'")
first()
Selle kompileerimisel saame
Traceback (most recent call last):
File "<path to the file>", line 18, in <module>
first()
File "<path to the file>", line 15, in first
second("The output is called ", "'Stack Trace'")
File "<path to the file>", line 10, in second
first(c)
File "<path to the file>", line 2, in third
print(int(a)) # Attempt to convert string <The output is called 'Stack Trace'> to int and print it out
ValueError: invalid literal for int() with base 10: "The output is called 'Stack Trace'"
Väljundis on näha kogu protsessi, mille teostamisel tekkis viga. Ülevalt alla:
Kompilaator märkas funktsiooni first() kutset ja läks sinna (rida 16, antud mooduli sees)
Funktsioon first() omakorda kutsub teise funktsiooni, second() meie poolt määratud parameetritega (rida 13, funktsiooni first() sees)
Funktsioon second() teeb stringi liitmist ja kutsub funktsiooni third() (rida 9, funktsiooni second() sees)
Vea tekkimise koht: proovides teisendada argumenti a numbriks, saime
ValueError: invalid literal for int() with base 10: "The output is called 'Stack Trace'"