Domknięcia i zmienne wolne
Przechwytuj stan w funkcjach wewnętrznych
Domknięcia i zmienne wolne to bezpłatna lekcja Python Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Python Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Python Academy zawiera 4 lekcji w sumie.
Funkcje zagnieżdżone
Python pozwala definiować funkcję wewnątrz innej funkcji. Funkcja wewnętrzna jest tworzona od nowa przy każdym uruchomieniu funkcji zewnętrznej.
def outer():
def inner():
return 'from inner'
return inner()
print(outer())Funkcja wewnętrzna widzi zmienne zewnętrzne
Funkcja wewnętrzna może odczytywać zmienne zdefiniowane w funkcji ją otaczającej. Są one nazywane zmiennymi wolnymi, ponieważ nie są lokalne dla funkcji wewnętrznej.
def outer():
message = 'hello'
def inner():
return message
return inner()
print(outer())Czym jest domknięcie?
Domknięcie powstaje, gdy funkcja wewnętrzna zostaje zwrócona i nadal pamięta zmienne wolne ze swojego zakresu zewnętrznego, nawet po zakończeniu tego zakresu.
def make_greeter(name):
def greet():
return 'Hi ' + name
return greet
g = make_greeter('Ada')
print(g())Przechwycony stan zostaje zachowany
Funkcja zewnętrzna już się zakończyła, ale domknięcie nadal przechowuje name. Wartość pozostaje dostępna wewnątrz zwróconej funkcji.
def make_greeter(name):
def greet():
return 'Hi ' + name
return greet
a = make_greeter('Ada')
b = make_greeter('Bob')
print(a())
print(b())Fabryka mnożników
Domknięcia doskonale sprawdzają się jako fabryki tworzące dostosowane funkcje. W tym przykładzie każda zwrócona funkcja mnoży przez przechwycony współczynnik.
def multiplier(factor):
def multiply(n):
return n * factor
return multiply
double = multiplier(2)
triple = multiplier(3)
print(double(10))
print(triple(10))Każde domknięcie jest niezależne
Każde wywołanie fabryki tworzy osobne domknięcie z własną przechwyconą wartością. Domknięcia nie wpływają na siebie nawzajem.
def adder(amount):
def add(n):
return n + amount
return add
add5 = adder(5)
add100 = adder(100)
print(add5(1), add100(1))Sprawdzanie wartości przechwyconych przez domknięcie
Przechwycone nazwy są wymienione w __code__.co_freevars, a ich wartości znajdują się w komórkach __closure__.
def make(x):
def f():
return x
return f
fn = make(42)
print(fn.__code__.co_freevars)
print(fn.__closure__[0].cell_contents)Domknięcia przechwytują zmienne, nie wartości
Domknięcie przechwytuje samą zmienną, więc widzi jej końcową wartość. Ma to znaczenie, gdy zmienna zmieni się po utworzeniu domknięcia.
def build():
x = 1
def show():
return x
x = 99
return show
print(build()())Pułapka późnego wiązania w pętli
To klasyczna pułapka: domknięcia utworzone w pętli współdzielą tę samą zmienną pętli, więc przechwytują jej ostatnią wartość.
funcs = []
for i in range(3):
funcs.append(lambda: i)
print([f() for f in funcs])Naprawianie późnego wiązania
Należy powiązać bieżącą wartość z argumentem domyślnym, aby każde domknięcie przechwytywało własną kopię w chwili definicji.
funcs = []
for i in range(3):
funcs.append(lambda i=i: i)
print([f() for f in funcs])Domknięcia jako lekkie obiekty
Domknięcie łączy dane z zachowaniem, podobnie jak mały obiekt — w prostych przypadkach często jest przejrzystszym rozwiązaniem niż pełna klasa.
def counter_start(start):
def value():
return start
return value
c = counter_start(10)
print(c())Szybki test
Czym jest domknięcie w Pythonie?
Podsumowanie: domknięcia i zmienne wolne
Najważniejsze informacje:
- Funkcje wewnętrzne mogą odczytywać zmienne z zakresu zewnętrznego (zmienne wolne).
- Domknięcie to zwrócona funkcja wewnętrzna, która pamięta te zmienne.
- Każde wywołanie fabryki tworzy niezależne domknięcie.
- Domknięcia przechwytują zmienne, a nie wartości, co powoduje pułapkę późnego wiązania w pętli — można ją naprawić za pomocą argumentu domyślnego.
def power_of(exp):
return lambda base: base ** exp
square = power_of(2)
print(square(9))Często zadawane pytania
Czy lekcja „Domknięcia i zmienne wolne” jest bezpłatna?
Tak — pełny tekst „Domknięcia i zmienne wolne” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Python Academy, przejdź na CoddyKit PRO. Kurs Python Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Domknięcia i zmienne wolne”?
Przechwytuj stan w funkcjach wewnętrznych Ćwiczysz Python Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Python Academy?
Nie wymagamy żadnego doświadczenia. Python Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „Domknięcia i zmienne wolne”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Python Academy?
Tak. Każda lekcja Python Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Funkcje pierwszej klasy
- Domknięcia i zmienne wolne
- nonlocal i stan zmienny
- Funkcje częściowe