- Bağlantıyı al
- X
- E-posta
- Diğer Uygulamalar
- Bağlantıyı al
- X
- E-posta
- Diğer Uygulamalar
Kapsülleme, temel olarak veriyi (nitelikleri) ve o veriyi işleyen metotları (davranışları) tek bir birim, yani sınıf içinde paketleme sürecidir.
Ancak kapsüllemenin daha derin ve kritik bir anlamı daha vardır: Veriye Doğrudan Erişimi Kısıtlama.
Bir nesnenin dahili verilerinin (niteliklerinin) dışarıdan rastgele ve kontrolsüz bir şekilde değiştirilmesini engellemektir. Bu, nesnenin her zaman geçerli ve tutarlı bir durumda kalmasını sağlar.
Örnek Senaryo: Bir BankaHesabi nesnesinde, hesap bakiyesinin negatif olmaması gerekir. Eğer kullanıcı hesap.bakiye = -1000 gibi bir atama yapabilirse, nesne tutarsız hale gelir. Kapsülleme, bu tür direkt atamaları engeller.
Diğer bazı programlama dillerinde (Java, C++), nitelikleri private (özel) olarak tanımlayarak dışarıdan erişimi tamamen engelleyen katı kurallar varken, Python'da bu mekanizma yoktur.
Python, bunun yerine geliştiriciler arasında bir kural (convention) kullanır:
Tek Alt Çizgi (_): Korunmuş (Protected) Nitelik
_bakiye gibi tek bir alt çizgi ile başlayan nitelikler, bu niteliğe dışarıdan dokunulmaması gerektiğini gösteren bir uyarı işaretidir.
Teknik olarak erişilebilir, ancak geliştiriciler bu kurala uymalıdır.
Çift Alt Çizgi (__): İsim Karıştırma (Name Mangling)
__bakiye gibi çift alt çizgi ile başlayan nitelikler, Python tarafından otomatik olarak sınıf ismini de içerecek şekilde yeniden adlandırılır (Örn: _SınıfAdı__bakiye).
Bu, dışarıdan doğrudan erişimi çok zorlaştırır (ancak tamamen engellemez).
Örnek: Kapsüllemeyi Uygulama
class BankaHesabi:
def __init__(self, bakiye):
# Niteliklerin adının başına alt çizgi koyarak
#"özel" olduğunu belirtiyoruz
self.__bakiye = bakiye
# 1. Getter Metodu (Veriyi Okuma)
def bakiyeyi_goster(self):
return f"Mevcut Bakiye: {self.__bakiye} TL"
# 2. Setter Metodu (Veriyi Kontrollü Değiştirme)
def para_yatir(self, miktar):
if miktar > 0:
self.__bakiye += miktar
print(f"{miktar} TL yatırıldı.")
else:
print("Hata: Yatırılan miktar pozitif olmalıdır.")
# Kullanım
hesap = BankaHesabi(1000)
# KONTROLSÜZ ERİŞİM GİRİŞİMİ (Çalışmaz)
# hesap.__bakiye = -500 # Doğrudan atama çalışmaz veya
#beklenmedik sonuç verir
# KONTROLLÜ ERİŞİM (Setter metodu kullanılır)
hesap.para_yatir(200) # Doğru işlem: 200 TL yatırıldı.
# KONTROLLÜ OKUMA (Getter metodu kullanılır)
print(hesap.bakiyeyi_goster()) # Çıktı: Mevcut Bakiye: 1200 TL
Kapsülleme uygulandığında, nesnenin niteliğine dışarıdan doğrudan erişmek yerine, iki özel metot kullanılır:
Getter Metotları: Özel niteliğin değerini dış dünyaya okumak için kullanılır.
Setter Metotları: Özel niteliğin değerini dış dünyadan gelen istekle kontrol ederek değiştirmek için kullanılır.
Kapsülleme, kodun bütünlüğünü korumak ve olası hataları en aza indirmek için kritik öneme sahiptir. Python, katı erişim kısıtlamaları yerine geliştirici sorumluluğuna dayansa da, özel nitelikleri tanımlamak ve kontrollü erişim için Getter/Setter metotlarını kullanmak en iyi OOP uygulamasıdır.
class Siparis:
def __init__(self, fiyat):
# Özel nitelik
self.__fiyat = fiyat
# 1. Getter Metodu (Değeri OKUR)
def get_fiyat(self):
return self.__fiyat
# 2. Setter Metodu (Değeri KONTROL EDEREK YAZAR)
def set_fiyat(self, yeni_fiyat):
# Kapsülleme Mantığı: Negatif fiyatı engelle
if yeni_fiyat > 0:
self.__fiyat = yeni_fiyat
else:
print("Hata: Fiyat pozitif olmalıdır! Değişiklik yapılmadı.")
# Kullanım
siparis = Siparis(100)
# Okuma: Getter kullanılır
print(f"Mevcut Fiyat: {siparis.get_fiyat()}")
# Çıktı: Mevcut Fiyat: 100
# Yazma: Setter kullanılır, kontrol devreye girer
siparis.set_fiyat(-50) # Çıktı: Hata: Fiyat pozitif olmalıdır!
print(f"Yeni Fiyat: {siparis.get_fiyat()}")
# Çıktı: Yeni Fiyat: 100 (Değişmedi)
@property DekorâtörüGeleneksel Getter/Setter metotlarının çağrılması (siparis.get_fiyat()), normal bir nitelik erişimi (siparis.fiyat) gibi hissettirmez. Python, bu sorunu @property dekoratörü ile çözer.
@property kullanıldığında, metotlar tanımlansa bile, dışarıdan erişim tıpkı bir nitelikmiş gibi görünür.
Getter: Metodun üzerine sadece @property konur.
Setter: Metodun üzerine @<getter_ismi>.setter konur.
class SiparisGelistirilmis:
def __init__(self, fiyat):
# __fiyat özel nitelik olmaya devam eder
self.__fiyat = fiyat
@property # 1. GETTER (Okuma)
def fiyat(self):
# Bu metot, 'siparis.fiyat' diye çağrıldığında çalışır
return self.__fiyat
@fiyat.setter # 2. SETTER (Yazma)
def fiyat(self, yeni_fiyat):
# Bu metot, 'siparis.fiyat = X' diye atama yapıldığında
#çalışır
if yeni_fiyat > 0:
self.__fiyat = yeni_fiyat
else:
print("Hata:Fiyat pozitif olmalıdır! Değişiklik yapılmadı.")
# Kullanım
siparis_gel = SiparisGelistirilmis(200)
# Okuma, sanki nitelikmiş gibi (Getter çalışır)
print(f"Mevcut Fiyat: {siparis_gel.fiyat}") # Çıktı: 200
# Yazma, sanki nitelikmiş gibi (Setter çalışır, kontrol devreye girer)
siparis_gel.fiyat = 300 # Geçerli atama
siparis_gel.fiyat = -80 # Hata mesajı verir
print(f"Son Fiyat: {siparis_gel.fiyat}") # Çıktı: 300@property dekoratörleri, kapsüllemeyi uygulamanın Python'daki en tavsiye edilen ve "Pythonic" yoludur. Bu sayede, nesnenizin bütünlüğünü koruyan kontrolleri arka planda tutarken, dış arayüzü basit ve temiz (nesne.nitelik) tutabilirsiniz.
Hemen kursumuza kaydolun ve bu güçlü araçları kullanarak profesyonel Python geliştiricisi olma yolunda ilk adımı atın. Kursumuzdaki uygulamalı modüller, sizi sadece bir yazılımcı adayı değil, hazır bir profesyonel haline getirecek. Python Eğitimini Udemy platformunda bulabilirsiniz.
Yorumlar
Yorum Gönder