Closure'lar (kapamalar) Python'un güçlü bir mekanizmasıdır, çevre bağlamından 'hatırlanmış' verilere sahip fonksiyonlar yaratmaya olanak tanır.
Fonksiyonel dillerde ve Python'da fonksiyonlar birinci sınıf nesnelerdir. Bir fonksiyon, kendi çevresindeki (dış) görünüm bağlamındaki değişkenleri 'kapatan' yeni bir fonksiyon döndürebilir.
Geliştiriciler sıkça kapatılan değişkenlerin closure içinde nasıl 'yaşadığını', nasıl okunup yazıldığını, nasıl güvenli bir şekilde çalışılacağını (özellikle değiştirilebilir nesnelerle) karıştırır.
İç fonksiyon dış fonksiyondaki değişkenleri kullanırsa, bu değişkenler otomatik olarak 'hatırlanır' – dış fonksiyon çalışmayı tamamlamış olsa bile. Değişkeni okumak her zaman açıktır, ancak değeri değiştirmek gerektiğinde nonlocal anahtar kelimesini kullanmak gerekir. Değiştirilebilir nesnelerle (listeler, dict'ler) çalışırken bu özellikle riskli bir alandır.
Örnek:
def outer(): count = 0 def inner(): nonlocal count count += 1 return count return inner counter = outer() print(counter()) # 1 print(counter()) # 2
Anahtar özellikler:
nonlocal kullanın (aksi takdirde işlem yerel bir değişken yaratır).Nonlocal olmadan, bir fonksiyon içinde kapalı bir değişkenin değerini değiştirebilir miyiz?
Hayır. Yeni bir değer atamaya çalıştığınızda nonlocal belirtmeden Python bunu yeni bir yerel değişken oluşturma olarak algılar ve eski değer dışarı çıkmaz.
Örnek:
def make_counter(): count = 0 def inner(): count += 1 # UnboundLocalError! hatası! return count return inner
Closure aracılığıyla dış görünümde argümanlar iletebilir miyiz?
Evet, closure, sınıf nitelikleri, global değişkenler vb. dahil dış görünümdeki herhangi bir değişkeni 'hatırlayacaktır'. Ancak bu değişkenlerin değiştirilmesi, özel çabalar gerektirir (örneğin, nonlocal veya global kullanımı).
Closure içindeki değiştirilebilir nesnelerle ne olur?
Eğer kapalı bir referans, değiştirilebilir bir nesneye (örneğin bir liste) sahipse, içeriğini nonlocal olmadan değiştirebilirsiniz, ama eğer değişkeni yeniden atamaya çalışırsanız – nonlocal gerekecektir.
Örnek:
def make_appender(): result = [] def append(x): result.append(x) # Tamamdır! return result return append f = make_appender() print(f(1)) # [1] print(f(2)) # [1, 2]
Geliştirici bir closure yazar, değişkeni nonlocal olmadan değiştirir – UnboundLocalError oluşur.
Artılar:
Eksiler:
Closure'daki yönetilen durum için nonlocal kullanımı.
Artılar:
Eksiler: