10 tipuri comune de erori Python și cum să le rezolvi

Erori frecvente în Python și cum să le depășim

Ca dezvoltator de software, te vei confrunta inevitabil cu erori în procesul de creare a programelor. Acestea pot varia de la greșeli în logica ta, care duc la rezultate neașteptate, la încălcări ale regulilor limbajului de programare și chiar erori care apar în timpul execuției. Toate aceste erori sunt cunoscute sub numele de bug-uri.

Bug-urile sunt prezente în orice limbaj de programare, indiferent cât de facil este de învățat sau de folosit.

Chiar și în Python, un limbaj recunoscut pentru lizibilitatea sa, sintaxa expresivă și ușurința relativă în comparație cu alte limbaje, nu ești imun la erorile de programare.

Având în vedere că erorile sunt inevitabile, o abordare eficientă este să înveți despre diferitele tipuri de erori și cauzele lor. Această cunoaștere te va ajuta să le previi sau să le minimalizezi în timpul programării și să știi cum să le gestionezi când apar.

Iată câteva dintre erorile comune pe care le poți întâlni în Python:

SyntaxErrors

O eroare de sintaxă se produce atunci când scrii cod care nu respectă regulile limbajului de programare. Aceasta înseamnă că ai o linie de cod invalidă.

În Python, de exemplu, un șir de caractere trebuie inclus între ghilimele. Dacă uiți acest lucru, vei avea o eroare de sintaxă.

O eroare de sintaxă mai poate apărea când lipsește o paranteză (rotundă, pătrată sau acoladă), când ai cuvinte cheie sau nume de funcții greșite, când nu pui două puncte la sfârșitul instrucțiunilor de control sau când uiți operatorii necesari într-o expresie.

În general, erorile de sintaxă apar atunci când încalci orice regulă a modului în care trebuie scris codul în Python.

 ## eroare de sintaxă datorată lipsei ghilimelelor
 ## în jurul șirului de text
 print("Hello World)

 age = 20
 ## Eroare de sintaxă din cauza lipsei două puncte într-o instrucțiune if
 if age > 18
    print("Vârsta este mai mare de 18 ani")

 ## Eroare de sintaxă deoarece paranteza '(' nu a fost închisă
 def square(x:
    return x * x
 print(square(4))
 

La rularea codului de mai sus, vei primi un mesaj de eroare, după cum urmează:

Mesajul de eroare rezultat este:

   File "/home/madici/Desktop/helloworld.py", line 1
     print("Hello World)
           ^
 SyntaxError: unterminated string literal (detected at line 1)
 

Pentru a corecta aceste erori, trebuie să folosești sintaxa corectă a Python, după cum urmează:

 print("Hello World")

 age = 20
 if age > 18:
    print("Vârsta este mai mare de 18 ani")

 def square(x):
    return x * x
 print(square(4))
 

IndentationError

Spre deosebire de limbaje ca Java, C sau C++, care folosesc acolade pentru a delimita blocurile de cod, Python utilizează indentarea pentru a defini ierarhia și structura blocurilor de cod. De exemplu, în Java, codul care se execută după o condiție este inclus în acolade.

În Python, blocul de cod va fi indentat. O indentare tipică în Python este formată din patru spații sau un tab. Important este ca numărul de spații să fie consistent în tot codul.

Ca programator Python, te poți confrunta cu erori de indentare când uiți să adaugi indentarea necesară, de exemplu, la instrucțiunile de control sau funcții, când folosești atât tab-uri, cât și spații pentru indentare, ceea ce derutează interpretorul, când pui indentările în locul greșit sau când indentările nu sunt uniforme în tot codul.

Un exemplu de cod cu eroare de indentare este prezentat mai jos:

 age = 20
 if age > 18:
 print("Vârsta este mai mare de 18 ani")
    print("Ai voie să conduci")
 else:
    print("Vârsta este mai mică de 18 ani")
 

Mesajele de eroare rezultate din codul de mai sus sunt:

Mesajul de eroare generat la rularea codului este:

   File "/home/madici/Desktop/helloworld.py", line 3
     print("Vârsta este mai mare de 18 ani")
     ^
 IndentationError: expected an indented block after 'if' statement on line 2
 

Pentru a corecta erorile, este necesar să indentezi linia după instrucțiunea if și să te asiguri că se potrivește cu indentarea din restul codului, după cum urmează:

 age = 20
 if age > 18:
    print("Vârsta este mai mare de 18 ani")
    print("Ai voie să conduci")
 else:
    print("Vârsta este mai mică de 18 ani")
 

TypeError

În Python, o TypeError este o excepție care apare atunci când încerci să efectuezi o operațiune cu un tip de date incompatibil. De exemplu, dacă încerci să adaugi un șir de caractere și un număr întreg, sau să concatenezi un șir cu un întreg, vei avea o TypeError.

De asemenea, poți întâlni TypeErrors când folosești funcții sau metode cu tipuri de date incorecte, când încerci să folosești un index non-întreg pentru a accesa elemente dintr-un iterabil (cum ar fi o listă) sau când încerci să iterezi printr-un obiect care nu este iterabil.

În general, orice operație care folosește un tip de date nepotrivit va genera o TypeError.

Exemple de operații care pot duce la TypeErrors sunt prezentate mai jos:

 # TypeError datorat concatenării unui șir de caractere cu un număr întreg
 age = 25
 message = "Am " + age + " ani."


 list1 = [1, "hello", 5, "world", 18, 2021]
 #TypeError din cauza utilizării incorecte a metodelor predefinite
 print(sum(list1))

 #TypeError datorat adunării unui șir de caractere cu un număr întreg
 num1 = 10
 num2 = "16"
 print(num1 + num2)

 #TypeError datorat utilizării unui index non-întreg
 list2 = ["hello", "from", "the", "other", "side"]
 print(list2["1"])
 

Mesajele de eroare generate de codul de mai sus sunt:

Un exemplu de mesaj TypeError generat de cod este:

   File "/home/madici/Desktop/helloworld.py", line 3, in <module>
     message = "Am " + age + " ani."
               ~~~~~~~~^~~~~
 TypeError: can only concatenate str (not "int") to str
 

Pentru a elimina erorile, trebuie să folosești tipurile de date corecte sau conversiile de tip, după cum urmează:

 age = 25
 message = "Am " + str(age) + " ani."

 list1 = [1, 5, 18, 2021]
 print(sum(list1))

 num1 = 10
 num2 = "16"
 print(num1 + int(num2))

 list2 = ["hello", "from", "the", "other", "side"]
 print(list2[1])
 

AttributeError

În Python, o AttributeError apare când încerci să folosești un atribut care nu există pe un obiect sau să apelezi o metodă care nu există pe obiectul respectiv. O AttributeError indică faptul că obiectul nu are atributul sau metoda invocată.

De exemplu, dacă apelezi o metodă de șir pe un număr întreg, vei avea o AttributeError, deoarece metoda respectivă nu există pe acel tip de obiect.

În exemplul de mai jos, metoda `capitalize()`, folosită pentru a transforma prima literă a unui șir în majusculă, este apelată pe un număr întreg. Acest lucru va genera o eroare de atribut, deoarece numerele întregi nu au metoda `capitalize()`.

 # AttributeError datorată apelării capitalize() pe un număr întreg
 num = 1445
 cap = num.capitalize()
 print(cap)
 

Executarea acestui cod va genera următorul mesaj de eroare:

Mesajul AttributeError din cod este:

   File "/home/madici/Desktop/helloworld.py", line 3, in <module>
     cap = num.capitalize()
           ^^^^^^^^^^^^^^
 AttributeError: 'int' object has no attribute 'capitalize'
 

Pentru a rezolva o AttributeError, asigură-te că metoda sau atributul pe care îl apelezi există pe tipul de obiect respectiv. În acest caz, apelarea `capitalize()` pe un șir de caractere rezolvă eroarea, după cum urmează:

ImportError

În Python, o ImportError apare când încerci să imporți un modul care nu este găsit sau nu este accesibil în mediul tău. Modulul s-ar putea să nu fie instalat, calea să nu fie configurată corect sau numele să fie scris greșit.

O ImportError are o subclasă numită ModuleNotFoundError, care este generată când încerci să imporți un modul care nu este găsit.

De exemplu, codul de mai jos care încearcă să importe biblioteca panda, pentru analiza datelor, va genera o astfel de eroare dacă modulul nu este instalat.

Mesajul ImportError generat este:

   File "/home/madici/Desktop/helloworld.py", line 1, in <module>
     import pandas
 ModuleNotFoundError: No module named 'pandas'
 

Pentru a remedia o astfel de eroare, asigură-te că modulele pe care încerci să le imporți sunt instalate. Dacă eroarea persistă, verifică ortografia numelui modulului și calea corectă către modul.

ValueError

Aceasta este o excepție care apare când o funcție din Python primește o valoare de tipul corect, dar valoarea este inadecvată. De exemplu, funcția `math.sqrt()`, folosită pentru a calcula rădăcina pătrată a unui număr, va returna o ValueError dacă primește un număr negativ.

Chiar dacă valoarea este de tipul corect (numerică), dacă este negativă, devine inadecvată pentru funcție.

Funcția `int()`, care convertește un număr sau un șir de caractere într-un număr întreg, va genera o ValueError dacă primește un șir care nu este numeric. Dacă folosești „123” sau „45”, nu va genera eroare, deoarece aceste șiruri pot fi convertite în numerele întregi corespunzătoare.

Dar, dacă introduci un șir care nu este numeric, cum ar fi „Bună ziua”, funcția va genera o ValueError, deoarece „Bună ziua” nu are un echivalent întreg.

Un exemplu de cod care generează o ValueError este:

 # ValueError datorată valorii inadecvate din sqrt()
 import math
 num = -64
 root = math.sqrt(num)
 print(root)

 # ValueError datorată unui șir non-numeric în funcția int()
 numString = "Bună ziua"
 num = int(numString)
 print(num)
 

Erorile din codul de mai sus sunt:

Mesajul de eroare generat este:

   File "/home/madici/Desktop/helloworld.py", line 4, in <module>
     root = math.sqrt(num)
            ^^^^^^^^^^^^^^
 ValueError: math domain error
 

Pentru a corecta eroarea, trebuie să folosești valori adecvate, după cum urmează:

 import math
 num = 64
 root = math.sqrt(num)
 print(root)

 numString = "5231"
 num = int(numString)
 print(num)
 

IOError

IOError (eroare de intrare/ieșire) este o excepție care apare când o operație de intrare sau ieșire eșuează. Acest lucru poate fi cauzat de încercarea de a accesa un fișier inexistent, de spațiu insuficient pe disc, de accesarea unui fișier pentru care nu ai permisiuni sau când fișierul este folosit de altă operațiune.

Metode ca `open()`, `read()`, `write()` și `close()`, folosite când lucrezi cu fișiere, sunt cele care pot genera această eroare.

Codul de mai jos încearcă să deschidă un fișier numit „notes.txt”, care nu există. Aceasta va genera o IOError, care se va concretiza printr-o FileNotFoundError:

Cu următorul mesaj de eroare:

   File "/home/madici/Desktop/helloworld.py", line 2, in <module>
     file1 = open("notes.txt", "r")
             ^^^^^^^^^^^^^^^^^^^^^^
 FileNotFoundError: [Errno 2] No such file or directory: 'notes.txt'
 

Pentru a evita eroarea, asigură-te că fișierul „notes.txt” există în directorul în care rulezi scriptul. O altă metodă de a gestiona erorile IO este să folosești un bloc `try except`, după cum se vede mai jos:

NameError

NameError este o excepție pe care o vei întâlni când încerci să folosești o variabilă, o funcție sau un modul care nu există, nu este definit în domeniul curent sau nu are o valoare atribuită.

Această eroare apare de obicei când scrii greșit numele unei variabile sau funcții, sau când le folosești înainte de a fi definite. Folosirea unui modul fără a-l importa va genera, de asemenea, o NameError.

Următorul cod va genera o excepție NameError:

 # NameError deoarece modulul math nu a fost importat
 num = 64
 root = math.sqrt(64)
 print(root)

 # NameError deoarece x este folosită înainte de a fi definită
 y = 23
 print(x)

 #NameError deoarece numele funcției nu este definit corect
 def greet():
     print("Bună dimineața")
 great() #NameError: name 'great' is not defined
 

Mesajele de eroare generate de codul de mai sus sunt:

Un exemplu de mesaj NameError este:

   File "/home/madici/Desktop/helloworld.py", line 3, in <module>
     root = math.sqrt(64)
            ^^^^
 NameError: name 'math' is not defined
 

Pentru a rezolva o astfel de NameError, asigură-te că nu folosești module înainte de a le importa, nu folosești variabile sau funcții înainte de a le defini și nu scrii greșit numele funcțiilor sau variabilelor:

 import math
 num = 64
 root = math.sqrt(64)
 print(root)

 y = 23
 print(y)

 def greet():
     print("Bună dimineața")
 greet()
 

IndexError

O IndexError este o excepție care apare când încerci să accesezi un index dintr-o listă sau un tuplu care este în afara intervalului. Să luăm în considerare lista de mai jos:

 list1 = [1, 2, 3, 4, 5]
 

Lista are cinci elemente. Indicii în Python încep de la 0 (zero). Prin urmare, lista de mai sus are indicii de la 0 la n-1, unde n este numărul de elemente din listă. În acest caz, indexul listei este între 0 și 4.

Dacă încerci să accesezi un element la un index mai mare decât 4, vei avea o IndexError, deoarece indexul este în afara intervalului listei. Codul de mai jos generează o IndexError:

 list1 = [1, 2, 3, 4, 5]
 item = list1[6] #IndexError deoarece indexul listei este în afara intervalului
 print(item)
 

Eroarea din cod este prezentată mai jos:

Mesajul IndexError generat este:

   File "/home/madici/Desktop/helloworld.py", line 2, in <module>
     item = list1[6] #IndexError because the list index is out of range
            ~~~~~^^^
 IndexError: list index out of range
 

Cea mai bună metodă de a evita o IndexError este să folosești funcțiile `range()` și `len()` pentru a accesa doar elementele aflate în interval, după cum urmează:

 list1 = [1, 2, 3, 4, 5]

 for i in range(len(list1)):
     print(list1[i])
 

KeyError

O KeyError este o excepție care apare când încerci să accesezi un element dintr-un dicționar folosind o cheie care nu există în acel dicționar. Să luăm în considerare dicționarul de mai jos:

 cities = {"Canada": "Ottawa", "USA": "Washington", "Italy": "Rome"}
 

Cheile din dicționar sunt „Canada”, „USA”, „Italy”. Poți accesa elementele din dicționarul `cities` folosind aceste trei chei. Dacă încerci să accesezi un element folosind o cheie care nu există, cum ar fi „Brazilia”, vei întâmpina o KeyError, după cum se vede mai jos:

Mesajul KeyError generat este:

   File "/home/madici/Desktop/helloworld.py", line 6, in <module>
     print(cities["Brazil"])
           ~~~~~~^^^^^^^^^^
 KeyError: 'Brazil'
 

Pentru a rezolva o KeyError, asigură-te că cheile pe care le folosești pentru a accesa elementele dintr-un dicționar sunt prezente în acel dicționar. Pentru a face acest lucru, poți folosi o instrucțiune `if…else`, ca aceasta:

 cities = {"Canada": "Ottawa", "USA": "Washington", "Italy": "Rome"}

 country = "Canada"

 if country in cities:
     print("Capitala țării " + country + " este " + cities[country])
 else:
 	print("Cheia " + country + " nu este prezentă în dicționarul cities")
 

În acest fel, vei evita erorile KeyError atunci când accesezi elemente dintr-un dicționar.

Concluzie

Când scrii cod în Python, indiferent de nivelul tău de experiență, vei întâlni inevitabil erori. De aceea, este important să te familiarizezi cu diferitele tipuri de erori prezentate în acest articol, pentru a te asigura că le poți gestiona corespunzător când apar.

Poți explora și diverse versiuni utile de Python pentru a simplifica sarcinile frecvente.