Soru tarihi
Klasik nesne yönelimli programlamada kapsülleme, iç verilere erişimi kısıtlayarak uygulanır. Çoğu dilde katı erişim modifikatörleri vardır. Python'da "hepimiz yetişkiniz" prensibi geçerlidir — katı bir özel durum yoktur.
Sorun
Geliştiriciler, Python'daki korumalı (_protected) ve özel (__private) nitelikleri ve yöntemleri karıştırıyor, "çift alt çizgi"nin tam koruma sağladığını düşünüyor ya da tamamen korunma olmadığına inanıyorlar.
Çözüm
Python, anlaşmaları gerçekleştirir: tek alt çizgi _var — korumalı, çift alt çizgi __var — özel (isim mangling). Böyle bir niteliğe veya metoda erişim mümkündür, ancak daha zordur: _ClassName__var olarak çağrılır.
Kod örneği:
class Example: def __init__(self): self._protected = 1 # korumalı self.__private = 2 # özel (isim mangling) ex = Example() print(ex._protected) # 1 #print(ex.__private) # AttributeError print(ex._Example__private) # 2 (isim mangling)
Ana özellikler:
Bir örnek üzerinden "özel" alana erişebilir miyiz?
Evet, mangling yoluyla: _ClassName__var. Yani veriler erişilebilir, sadece açık değildir.
Özel yöntem/nitelik miras alındığında nasıl davranır?
İsim mangling, miras alanların ebeveynin özel ögelerini yanlışlıkla yeniden tanımlamasını engeller, fakat erişim sağlanabilir: _ParentClass__attr üzerinden. Çift alt çizgili yöntemler, miras alan sınıfından dışarıdan "görünmez".
class A: def __foo(self): print("A") class B(A): def bar(self): # self.__foo() — hata self._A__foo() # çalışıyor
Python'da JVM/C++ seviyesinde tam özellik var mı?
Hayır. Her şey anlaşmalara ve manglinge dayanır. Verileri tamamen korumak mümkün değildir, çünkü Python dinamik olarak herhangi bir niteliğe erişim sağlar.
Büyük bir kütüphanede kullanıcı, özel bir niteliği çift alt çizgi ile değiştirmeye çalıştı, bunun "gizli" olduğunu düşündü — ancak _ClassName__var aracılığıyla değişiklik yine gerçekleşti.
Artılar:
Eksiler:
Bir projede, iç alanlar için tek alt çizgi kullanma konusunda anlaşıldı ve bunlara sınıf dışında dokunulmaması gerekti. Güvenli erişim için property eklendi.
Artılar:
Eksiler: