Wprowadzenie.
We wpisie przedstawiłem w jaki sposób w pythonie tworzymy funkcję wewnątrz funkcji. Na wstępie warto jeszcze zaznaczyć, że funkcja taka jest nazywana funkcją zagnieżdżoną (nested function).
Zakres artykułu.
- Funkcja w funkcji
Funkcja w funkcji
W pierwszym kroku napiszmy prostą funkcję zagnieżdżoną. W tym celu stwórzmy pierwszą normalną funkcję (funkcja zewnętrzna) fun1(), a w niej stwórzmy drugą funkcję (funkcja zagnieżdżona) fun2(). Po stworzeniu funkcji zagnieżdżonej od razu wywołajmy naszą funkcję zagnieżdżoną wewnątrz funkcji zewnętrznej fun1(). Abyśmy wiedzieli, w którym miejscu się znajdujemy wykorzystajmy do naszej nawigacji kilka printów, tak aby jeden wykonał się przed zadeklarowaniem funkcji zagnieżdżonej fun2(), drugi niech wykona się wewnątrz funkcji zagnieżdżonej fun2(), a trzeci niech wykona się po wywołaniu funkcji zagnieżdżonej fun2(). Na koniec w programie głównym wywołajmy funkcję fun1(). Kod całego programu wygląda następująco.
def fun1(): print("To jest fun1") def fun2(): print("To jest fun2") fun2() print("To jest ponownie fun1") fun1()
Po uruchomieniu programu w konsoli powinniśmy otrzymać następujący wynik.
To jest fun1
To jest fun2
To jest ponownie fun1
Jak widzimy, analizując krok po kroku program wszystko powinno być logicznie i bez większego problemu domyślamy się w którym momencie zostanie wywołany, konkretny print.
W drugim przykładzie zmodyfikujmy nieco nasz program, tak aby funkcja zewnętrzna fun1() przyjmowała argument. Następnie sprawdźmy, czy mamy dostęp do tego parametru wewnątrz naszej funkcji zagnieżdżonej fun2(). W tym celu ostateczny kod programu powinien wyglądać następująco.
def fun1(text): print("To jest fun1") def fun2(): print("To jest fun2") print(text) fun2() print("To jest ponownie fun1") fun1("To jest mój tekst")
Po wykonaniu programu w konsoli powinniśmy ujrzeć następujący wynik.
To jest fun1
To jest fun2
To jest mój tekst
To jest ponownie fun1
Jak widzimy wewnątrz funkcji zagnieżdżonej mamy dostęp do zmiennych z funkcji zewnętrznej, lecz w tym miejscu musimy się zatrzymać i sprawdzić jak dokładnie wygląda sytuacja ze zmiennymi w takich funkcjach.
W trzecim przykładzie dodajmy do naszej funkcji zewnętrznej fun1() trzy zmienne x, y, z, do których przypiszmy dowolne wartości. W funkcji zagnieżdżonej zmienną x zadeklarujmy poprzez słowo kluczowe nonlocal. Następnie w funkcji zagnieżdżonej fun2() do x i do y przypiszmy inne wartości natomiast zmienną z pozostawiamy w spokoju. Teraz w celu przetestowania sprawdźmy jakie wartości mają nasze zmienne x, y, z w funkcji zagnieżdżonej oraz jakie wartości mają te same zmienne po wywołaniu funkcji zagnieżdżonej fun2() w funkcji zewnętrznej fun1().
def fun1(text): x = 1 y = 2 z = 3 print("To jest fun1") def fun2(): nonlocal x x = 5 y = 6 print("To jest fun2") print(text) print("x w fun2", x) print("y w fun2", y) print("z w fun2", z) fun2() print("To jest ponownie fun1") print("x w fun1", x) print("y w fun1", y) print("z w fun1", z) fun1("To jest mój tekst")
Po wykonaniu programu w konsoli powinniśmy ujrzeć następujący wynik.
To jest fun1
To jest fun2
To jest mój tekst
x w fun2 5
y w fun2 6
z w fun2 3
To jest ponownie fun1
x w fun1 5
y w fun1 2
z w fun1 3
Jak widzimy zmienne dostępne w funkcji zagnieżdżonej zostały nadpisane, a w przypadku zmiennej z po prostu mamy do niej dostęp. Jak już wyjdziemy z funkcji zagnieżdżonej, wówczas widzimy, że zmienna x, która została zadeklarowana słowem kluczowym nonlocal, jej wartość również została nadpisana w funkcji zewnętrznej fun1(). To zachowanie po prostu możemy porównać do zastosowania słowa kluczowego global w przypadku zwykłych funkcji.