Rozdział 13 · Automatyzacja z funkcjami

Mini-projekt — Turtle Function Studio

Kształty z rozdziałów 6 i 10 stają się prawdziwą wielokrotnego użytku funkcją z wyraźnymi parametrami — i zamykamy cały rozdział funkcji.

Zastosowanie
defпараметрыциклыTurtle
Poziom
★★★★ challenge
Rezultat
Turtle graficznych

Co tworzymy

Projekt końcowy rozdziału: przekształcimy powtarzający się kod rysowania figur z rozdziałów 6 i 10 w prawdziwą, wielokrotnego użytku funkcję z parametrami.

Przepływ danych funkcji

WYZWANIEdraw_polygon(artist,6, 80)PARAMETRYartist, sides=6,length=80OBLICZENIAangle = 360 / sidesCYKLsides razyPRAWDZIWE WNIOSKIsześciokąt
Jeden wywołanie — parametry rozwijają się w obliczenie, pętlę i wynikowy rysunek
draw_polygon.py
import turtle

screen = turtle.Screen()
screen.setup(width=300, height=300)
artist = turtle.Turtle()
artist.speed(0)
artist.pencolor("#5B24F9")
artist.pensize(3)

def draw_polygon(artist, sides, length):
    angle = 360 / sides
    for _ in range(sides):
        artist.forward(length)
        artist.right(angle)

draw_polygon(artist, 6, 80)

screen.exitonclick()
Rezultat
Regularny sześciokąt rysowany przez funkcję draw_polygon
draw_polygon(artist, 6, 80) — prawidłowy sześciokąt

Dlaczego funkcja przyjmuje artist jawnie

figura_funkciya.py
def draw_polygon(artist, sides, length):
    angle = 360 / sides
    for _ in range(sides):
        artist.forward(length)
        artist.right(angle)

draw_polygon(artist, 4, 100)    # kwadrat
draw_polygon(artist, 3, 100)    # trójkąt, bez powtarzania kodu!
draw_polygon(artist, 8, 60)     # ośmiokąt
Parametr artist jawny nie jest zbędną formalnością
Funkcja mogłaby polegać na zmiennej globalnej artist, jak w rozdziale 10. Ale parametr sprawia, że zależność jest WIDOCZNA (§13.15): od razu widać, że funkcja działa dokładnie z tą żółwikiem, którą jej przekazano — można ją ponownie wykorzystać z inną żółwikiem (na przykład podczas wyścigu Turtle z §12.6, gdzie jest kilka żółwi) bez żadnej zmiany kodu wewnątrz.

Funkcja wewnątrz pętli: to samo zachowanie, nowy parametr na każdym kroku

figury_v_cikle.py
cveta = ["#5B24F9", "#DB2777", "#059669"]
for i, sides in enumerate(range(3, 9)):
    artist.pencolor(cveta[i % 3])
    draw_polygon(artist, sides, 70)
    artist.right(15)
figury_v_cikle.py
import turtle

screen = turtle.Screen()
screen.setup(width=420, height=420)
artist = turtle.Turtle()
artist.speed(0)
artist.pensize(2)

def draw_polygon(artist, sides, length):
    angle = 360 / sides
    for _ in range(sides):
        artist.forward(length)
        artist.right(angle)

cveta = ["#5B24F9", "#DB2777", "#059669"]
for i, sides in enumerate(range(3, 9)):
    artist.pencolor(cveta[i % 3])
    draw_polygon(artist, sides, 70)
    artist.right(15)

screen.exitonclick()
Rezultat
Wachlarz z sześciu obróconych wielokątów od trójkąta do ośmiokąta, narysowany pętlą wywołującą draw_polygon
Pętla powoduje draw_polygon z nowym sides na każdym kroku — wachlarzem wielokątów
Pętla automatyzuje powtarzanie, funkcja automatyzuje zachowanie
Dokładnie idea §13.1: pętla decyduje ILE RAZY i z jakimi danymi wywołać draw_polygon; sama funkcja decyduje, JAK narysować wielokąt na podstawie tych danych. Żadne z tych dwóch narzędzi nie zastępuje drugiego.
Challenge
Funkcja z pozycją

Dodaj parametry x, y (z domyślnymi wartościami 0, 0) do funkcji, aby móc określić, od czego zacząć rysować kształt.

Praktyka: Turtle Function Studio
Moduł turtle otwiera natywne okno Python – uruchamiane lokalnie w VS Code, PyCharm lub Jupyter
Praktyka kursuje lokalnie
Otwórz praktykę →

Podsumowanie rozdziału

Zestaw narzędzi do projektowania funkcji

Ostatni zestaw narzędzi rozdziału 13
Potrzebujesz ponownie użyć tego samego zestawu akcji?
→
wyróżnij funkcję
Czy funkcja wymaga wejścia?
→
parametry
Trzeba zwrócić wynik do przyszłego użytku?
→
return
Czy liczba kłótni może być nieznana?
→
*args / **kwargs
Czy niektóre argumenty powinny być opcjonalne?
→
domyślne ustawienia (niezmienialne!)
Niektóre argumenty powinny być przekazywane tylko po nazwie?
→
keyword-only, po *
Czy funkcja powinna zachowywać się przewidywalnie i łatwo ją testować?
→
czysta funkcja, bez efektów ubocznych
Czy trzeba przekazać samą funkcję jako wartość?
→
funkcja jest obiektem pierwszej klasy
Potrzebna jest malutka zasada dla sorted()/max()?
→
lambda
Pełna lista kontrolna projektu w §13.18

Czego nauczyliśmy się w tym rozdziale

  • Funkcja to nazwany, wielokrotnego użytku element zachowania: odbiera dane (parametry), pracuje z nimi, zwraca wynik (return).
  • Wywołanie funkcji przekazuje sterowanie do jej ciała i koniecznie wraca do miejsca wywołania — funkcja nie wykonuje się „gdzieś obok”
  • Parametr to nazwa w definicji, argument to wartość w wywołaniu. Przypisanie parametru i mutacja przekazanego obiektu to dwie różne akcje o różnych konsekwencjach na zewnątrz.
  • Domyślna wartość zmienna jest tworzona RAZ przy definiowaniu funkcji — użyj None jako sygnał zamiast [] lub {}.
  • *args oraz **kwargs zbierają zbędne argumenty w krotkę i słownik odpowiednio; to samo */** rozpakowuje kolekcję z powrotem w momencie rozmowy.
  • Funkcja bez return wciąż wraca None nie jest „niczym”
  • Python szuka nazwy zgodnie z zasadą LEGB: Local → Enclosing → Global → Builtins.
  • Funkcje wywołujące funkcje tworzą stos wywołań — a traceback z rozdziału 3 pokazuje ten stos w momencie wystąpienia błędu.
  • Funkcje — obiekty pierwszej klasy: można je zapisać pod inną nazwą, umieścić w kolekcjach, przekazać innym funkcjom (sorted(key=...)).
  • lambda — mała anonimowa funkcja dla jednego wyrażenia, nie więcej „nowoczesna" zamiana def.
  • Refaktoryzacja dużego skryptu do zestawu funkcji sprawia, że główny program jest czytelnym opisem algorytmu, a każda część jest niezależnie testowalna.

co dalej

Nauczyliśmy się grupować ZACHOWANIE w funkcjach. Ale w wielu naszych projektach dane i zachowanie, które z nimi współdziała, naturalnie idą w parze — kontakt z własnym telefonem, uczeń ze swoją oceną, żółw ze swoim kolorem i pozycją. W następnym rozdziale — „Tworzenie rzeczywistych obiektów” – nauczymy się, jak łączyć dane i funkcje, które współtworzą jedną nazwaną strukturę.