Python'da bir closure, dış değişkenlerin değerlerini "hatırlayan" bir fonksiyondur; bu, çağrıldığı kapsamın dışında bile geçerlidir. Closure'lar, iç fonksiyon dış fonksiyonda tanımlanan değişkenlere referans verdiğinde oluşturulur. Python 3'te iç fonksiyondan böyle değişkenleri değiştirmek için nonlocal anahtar kelimesi kullanılır.
Örnek:
def make_accumulator(): total = 0 def add(value): nonlocal total total += value return total return add acc = make_accumulator() print(acc(10)) # 10 print(acc(5)) # 15
nonlocal olmadan total değişkeninin değiştirilmesi mümkün olmazdı (UnboundLocalError hatası).
Soru: "İç içe bir fonksiyonda dış fonksiyonu nonlocal anahtar kelimesi olmadan artırmak mümkün mü?"
Cevap: Hayır, nonlocal olmadan bu hata verir, çünkü yorumlayıcı değişkeni iç fonksiyon için yerel olarak değerlendirir. Örnek:
def outer(): count = 0 def inner(): count += 1 # UnboundLocalError hatası return count return inner
Hikaye Bir web uygulamasında her işleyici için sayacı yerel olarak iç içe fonksiyonlar aracılığıyla uygulamak istediler, ancak
nonlocalkullanmayı unuttular. Sayaç her zaman 1 döndürüyordu, çünkü count'u yerel alanda hesaplıyor ve dış closure ile bağlantılı olmayan yeni bir tane artırıyordu.
Hikaye Paralelleştirme (multithreading) görevlerinde sıkça closures ve lambdalar kullanılır. Closures'ın anlaşılmaması durumunda, tüm lambda fonksiyonlarının döngü değişkeninin en son değerini "hatırlama" durumu oluştu ve görevler birbirini kopyalayarak farklı görevleri işlemek yerine aynı işlemi yaptı.
Hikaye Doğru closure kullanılmadan bir dekoratör yazarken (dış scope'a parametre geçişi yapılmadı) durum, dekoratörün çağrılar arasında durumu toplayamadığı bir hale geldi; bu da beklenmeyen sonuçlara ve uygulamanın kararsız çalışmasına yol açtı.