Cel mai simplu debugging în Python

Cel mai simplu debugging în Python


Debugger-ul pdb (Python Debugger) este o unealtă puternică și ușor de utilizat pentru depanarea codului Python. Acesta permite programatorilor să execute codul pas cu pas, să examineze valorile variabilelor și să identifice erorile logicii programului. În acest tutorial, vom explora caracteristicile principale ale pdb și vom demonstra utilizarea sa cu exemple practice.


Ce este pdb?

pdb este debugger-ul standard inclus în Python. Cu el, poți să:

  • Pui puncte de întrerupere (breakpoints) în cod.
  • Rulezi codul pas cu pas.
  • Examinezi sau modifici valorile variabilelor în timpul execuției.
  • Analizezi fluxul de execuție pentru a găsi erori.

Cum se pornește pdb?

Adăugam direct în cod un *breakpoint (punct de întrerupere):*

import pdb
pdb.set_trace()

sau

from pdb import set_trace as bp
bp()


Apelam scriptul Python cu debugger-ul din linia de comandă:

python3 -m pdb script.py



Comenzi Esențiale în pdb

Iată o listă de comenzi frecvent utilizate în pdb:

Comandă Descriere
l Listează codul din jurul poziției curente.
n Execută următoarea linie de cod.
s Intră într-o funcție (dacă este apelată).
c Continuă execuția până la următorul breakpoint.
p var Afișează valoarea variabilei var.
q Oprește debugger-ul și închide programul.
b Setează un breakpoint pe o anumită linie.
cl Șterge toate breakpoints.
h sau ? Afișează ajutorul pentru comenzi.

Exemplu Practic: Debugging cu pdb

Haideti sa exploram un program simplu care calculează factorialul unui număr, dar care conține o eroare.

def factorial(num):
    if num == 0:
        return 1
    return num * factorial(num)

def main():
    number = 5
    result = factorial(number)
    print(f"Factorialul lui {number} este {result}")

if __name__ == "__main__":
    main()


Rularea acestui cod va genera urmatoarea eroare:

Ceea ce inseamn că acest cod intră în buclă infinită din cauza unei erori logice.


Adaugă un punct de întrerupere

Folosim set_trace() pentru a întrerupe execuția înainte de a intra in functia care factorialul:

from pdb import set_trace as bp
def factorial(num):
    if num == 0:
        return 1
    return num * factorial(num)

def main():
    number = 5
    bp() # punctul in care executia va fi oprita
    result = factorial(number)
    print(f"Factorialul lui {number} este {result}")

if __name__ == "__main__":
    main()



Rulează programul

Rulează programul normal:

python script.py


Când ajunge la pdb.set_trace(), execuția se oprește, iar interfața pdb devine activă, similar cu imaginea de mai jos:


Conform tabelului de mai sus, haideti sa accesam comanda l pentru a afisa unde exact este oprit codul.

Pentru a intra cu debugger-ul in interiorul functiei folosim comanda s (step into). Daca introducem din nou l pentru a afisa pozitia cursorului putem vedea ca acesta se afla la inceputul functiei factorial

Pentru a accesa valoarea unei variabile putem scrie direct in terminal numele acestei variabile:

Deoarece avem acces direct la varibile, pdb suporta efectuarea diferitor operatii cu aceste variabile direct in terminal.

Pentru a continua la linia urmatoare folosim comanda n.

Atunci cand functia factorial este din nou apelata(fiind functie recursiva) introducem din nou comanda s pentru a intra in interiorul functiei. Daca afisam din nou valoarea variabilei num putem vedea ca valoarea nu s-a schimbar dupa prima iteratie - ceea ce duce la executarea acestui cod in mod infinit(bucla infinita). Pentru a rezolva problema va fi nevoie sa descrestem valoarea num in fiecare iteratie.
Pentru a intrerupe sesiunea de debugging introducem comanda q, iar apoi modificam codul pentru a aplica solutia:

def factorial(num):
    if num == 0:
        return 1
    return num * factorial(num - 1) # trebuie sa scadem 1

def main():
    number = 5
    result = factorial(number)
    print(f"Factorialul lui {number} este {result}")

if __name__ == "__main__":
    main()


Dupa ce accesam functia folosind comanda s si facem 2 iteratii putem vedea ca valoarea variabilei num a devenit 4 in loc de 5.


Acum ca am confirmat ca algoritmul nostru nu va rula la infinit putem lasa codul sa continue normal pana la finalul programului. Pentru a continua executia introducem comanda c.

Dupa executia programului putem vedea urmatorul mesaj afisat in terminal:

Factorialul lui 5 este 120


Concluzie

Debugger-ul pdb este esențial pentru identificarea erorilor și înțelegerea fluxului de execuție într-un program Python. Prin utilizarea punctelor de întrerupere, a comenzilor interactive și a capacității de a inspecta variabile, poți găsi rapid problemele din cod și le poți remedia.


Trebuie să fii autentificat pentru a accesa editorul de cod și pentru a experimenta codul prezentat în acest tutorial.

Intră în cont