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.
defпараметрыциклыTurtleCo 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
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()
Dlaczego funkcja przyjmuje artist jawnie
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
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
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)
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()
draw_polygon; sama funkcja decyduje, JAK narysować wielokąt na podstawie tych danych. Żadne z tych dwóch narzędzi nie zastępuje drugiego.Dodaj parametry x, y (z domyślnymi wartościami 0, 0) do funkcji, aby móc określić, od czego zacząć rysować kształt.
Podsumowanie rozdziału
Zestaw narzędzi do projektowania funkcji
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
Nonejako sygnał zamiast[]lub{}. *argsoraz**kwargszbierają zbędne argumenty w krotkę i słownik odpowiednio; to samo*/**rozpakowuje kolekcję z powrotem w momencie rozmowy.- Funkcja bez
returnwciąż wracaNonenie 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" zamianadef.- 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ę.