Rozdział 13 · Automatyzacja z funkcjami

Stos wywołań i traceback

Funkcje wywołujące funkcje tworzą stos oczekujących wywołań — a traceback z rozdziału 3 faktycznie pokazuje ten stos w momencie wystąpienia błędu.

Ramka wywoławcza (call frame)

Gdy funkcja jest wywoływana, Python tworzy tymczasowy „kontener”

call_frame.py
def area(width, height):
    return width * height

area(5, 3)
width5height3
Ramka wywołania area(5, 3): Parametry istnieją do momentu zakończenia danego wywołania

Funkcje mogą wywoływać inne funkcje

vlozhennye_vyzovy.py
def calculate_tax(amount):
    return amount * 0.2

def calculate_invoice(amount):
    tax = calculate_tax(amount)
    return amount + tax

calculate_invoice(100)

Pa calculate_tax() wykonuje się, wywołanie calculate_invoice() się nie kończy — „czeka” stos wywołań.

Stos rośnie i kurczy się

main← górze stosu
Krok 1 – Wykonanie głównego programu
calculate_invoice()← górze stosumain
Krok 2 – main spowodował calculate_invoice()
calculate_tax()← górze stosucalculate_invoice()main
Krok 3 — calculate_invoice wywołała calculate_tax(); stos na szczycie
calculate_invoice()← górze stosumain
Krok 4 – calculate_tax() zwrócił wynik i zniknął ze stosu
Ostatni wszedł — pierwszy wyszedł
Stos wywołań rośnie wraz z każdym nowym wywołaniem i maleje przy każdym zakończeniu – najnowsze wywołanie zawsze znajduje się na górze i kończy się pierwsze. Nazywa się to zasadą LIFO (Last In, First Out).

Traceback jest migawką stosu wywołań

Przypomnijmy sobie debugowanie z rozdziału 3: gdy pojawi się błąd, Python drukuje traceback — i to jest Dosłownie pokazuje łańcuch połączeń, który doprowadził do błędu:

traceback_primer.py
def divide(a, b):
    return a / b

def calculate():
    return divide(10, 0)

def main():
    calculate()

main()
Traceback (most recent call last):
  File "example.py", line 8, in <module>
    main()
  File "example.py", line 6, in main
    calculate()
  File "example.py", line 4, in calculate
    return divide(10, 0)
  File "example.py", line 2, in divide
    return a / b
ZeroDivisionError: division by zero
Każdy łańcuch znaków traceback to jedna klatka od stosu wywołań w momencie błędu
Czytanie traceback od dołu do góry
Najniższy łańcuch znaków — sama pomyłka. Linia nad nią — gdzie dokładnie się ona zdarzyła (divide). Powyżej – kto to wywołał (calculate), i jeszcze wyżej — kto wywołał tego (main). Traceback to dokładnie stos wywołań, który właśnie sobie wyobraziliśmy, pokazany w momencie, gdy coś poszło nie tak.
Praktyka: czytamy stos wywołań i traceback
interaktywny laptop bezpośrednio w przeglądarce – Python 3.14 przez Pyodide, bez instalacji
Otwórz praktykę →