Merhaba Arkadaşlar,
Mobilhanem.com da Python Eğitimi Serisinin bu dersinde Python Kapsülleme (Encapsulation) dersi ile birlikteyiz. Bir önceki derslerimizde nesne ve sınıf kavramlarını görmüştük.
Python Kapsülleme (Encapsulation) Nedir?
Kapsülleme, methotların ve variable’ların erişimlerini kısıtlamak anlamına geliyor. Biz metotlara veya variable’lara direk erişme ve değiştirme kısıtı özelliğini ekliyoruz. Peki bunu niye yapıyoruz? Çünkü yazdığımız kodların değiştirilmemesi yada değiştirdiğimiz değerlerin kontrollü olarak değiştirilmesi gerektiği için. İşte tam bu durumlarda kapsülleme sihirli bir değnek gibi imdadımıza yetişiyor. Şimdi örneklerle gösterelim.
class RegisterCourse: def __init__(self): self.name = "Ahmet" self.surname = "Kaleli" self.exam1 = 74 self.exam2 = 80 register = RegisterCourse() print("İsim : ",register.name) print("Soyisim : ",register.surname) print("Exam 1 : ",register.exam1) print("Exam 2 :",register.exam2)
RegisterCourse isminde sınıf oluşturduk. Şimdi sınıfımızın değişkenlerini görüntüleyelim
İsim : Ahmet Soyisim : Kaleli Exam 1 : 74 Exam 2 : 80
Yalnız burada bir problem var. Bu öğrencinin bilgilerine dışarıdan ulaşabiliyoruz hatta değiştirebiliyoruz.
register.exam1 = 50 register.exam2 = 60
Hemen bilgilere tekrar bakalım;
İsim : Ahmet Soyisim : Kaleli Exam 1 : 50 Exam 2 : 60
Gördüğünüz gibi öğrencinin kişisel bilgilerine ulaşabiliyor ve değiştirebiliyoruz. Peki bu kişinin bilgilerine dışarıdan ulaşılmasını ve değiştirilmesini nasıl kısıtlayabiliriz.
Python Encaplusation (Kapsüllem) Kullanımı
Kişinin bilgilerini global olarak oluşturduğumuz için herkes tarafında erişilebilir durumdadır. Bunun için biz verilerimizi ve metotlarımızı private(özel) olarak tanımlamamız gerekiyor. Nasıl yapıldığını hemen görelim.
Basit bir işlem, sadece oluşturduğumuz verilerin önüne “__” ekliyoruz, hemen deneyelim;
class RegisterCourse: def __init__(self): self.name = "Ahmet" self.surname = "Kaleli" self.__exam1 = 74 self.__exam2 = 80 register = RegisterCourse() print("İsim : ",register.name) print("Soyisim : ",register.surname) print("Exam 1 : ",register.exam1) print("Exam 2 :",register.exam2)
Şu şekilde bir hata aldık değil mi?
AttributeError: 'RegisterCourse' object has no attribute 'exam1'
Biz sınav bilgilerini private(özel) yaptığımız için sınav bilgilerine ulaşamadığından hata verdi. Artık bu değerlere yalnız bu sınıf içinde erişebiliriz. Peki diğer sınıflardan nasıl erişeceğiz? Yazıyı okumaya devam edelim. Peki aynı işlevleri methodlar içinde yapabiliyor muyuz? Hemen bir örnekle gösterelim.
class RegisterCourse: def __init__(self): self.name = "Ahmet" self.surname = "Kaleli" self.__exam1 = 74 self.__exam2 = 80 self.courses = [] def add(self,course): self.courses.append(course) register = RegisterCourse() register.add("Database Managment") print("İsim : ",register.name) print("Soyisim : ",register.surname) print(register.courses)
Gördüğünüz gibi Öğrencinin aldığı dersleri görebiliyor ve ders ekleyebiliyoruz. Şimdi bu method’da dışarıdan erişimi ve değiştirmeyi kısıtlayalım.
class RegisterCourse: def __init__(self): self.name = "Ahmet" self.surname = "Kaleli" self.__exam1 = 74 self.__exam2 = 80 self.courses = [] def __add(self,course): self.courses.append(course) register = RegisterCourse() register.add("Database Managment")
AttributeError: 'RegisterCourse' object has no attribute 'add'
Yine benzer bir hata aldık. add() diye bir metodumuz olduğu halde dışarıdan erişim olmadığı için (bunu methodun başına __ ekleyerek gerçekleştirdik ) erişemiyoruz.
Peki aklımıza şu gelebilir. Tamam sen benim dışarıdan exam1 ve exam2 değişkenlerine erişimini engelledim. Ben artık exam1 ve exam2 değişkenini hem okuyamıyorum hem de değiştiremiyorum. Ama ben en azından değeri okumak istiyorum, değiştirmezsem de olur 🙂
Kapsüllenmiş Verilere Dışarıdan Erişim
Peki bunun nasıl yapacağız? Hemen hemen bir çok programlama dilinde sıkla karşılaştığımız getter ve setter methodlarına benzer bir yapı ile yapacağız o zaman deneyelim.
class RegisterCourse: def __init__(self): self.name = "Ahmet" self.surname = "Kaleli" self.__exam1 = 74 self.__exam2 = 80 self.__courses = [] def __add(self,course): self.courses.append(course) def getExam1(self): return self.__exam1 register = RegisterCourse() print("İsim : ",register.name) print("Soyisim : ",register.surname) print("Exam 1 : ",register.getExam1())
Hemen Çıktıya bakalım.
İsim : Ahmet Soyisim : Kaleli Exam 1 : 4
Gördüğünüz gibi bu şekilde exam1 bilgisine ulaşmış olduk. Bu arada getExam1 ismini ben oluşturdum sizde başka isim verebilirsiniz. Bu yapı genel bir yapı olduğu için bu şekilde yazmanız (değişkenin başına get koyarak) kodlarınızın okunabilirliği artırabilir.
Peki değişken private olsa da ben hem erişmek hemde değerini değiştirmek istiyorum diyelim. Az önce sadece getter metodu eklemiştik şimdi birde setter methodu ekleyelim.
class RegisterCourse: def __init__(self): self.name = "Ahmet" self.surname = "Kaleli" self.__exam1 = 74 self.__exam2 = 80 self.__courses = [] def __add(self,course): self.courses.append(course) def getExam1(self): return self.__exam1 def setExam1(self, newVal): self.__exam1 = newVal register = RegisterCourse() print("İsim : ",register.name) print("Soyisim : ",register.surname) print("Exam 1 : ",register.getExam1())
Hemen çıktıya bakalım;
İsim : Ahmet Soyisim : Kaleli Exam 1 : 74
Gördüğünüz gibi not bilgisi değişmedi. Çünkü biz setExam1() fonksiyonunu çağırmadık hemen oluşturduğumuz setExam1() fonksiyonunu çağıralım.
register.setExam1(40)
Çıktıya bakalım;
İsim : Ahmet Soyisim : Kaleli Exam 1 : 40
Bu şekilde fonksiyonumuzu çağırmış olduk. Artık private değerleri setter fonksiyonu ile değiştirebilirsiniz.
Peki direk erişemiyorum ama setter methodu ile değişkeni istediğim gibi değiştirebildim. Neden getter setter ile uğraşayım. Neden private yapıp setter methodu kullanma gereği duydum? Çünkü direk eriştiğimde herhangi bir kontrol yapmadan değişkenin değerini değiştirebilirim. Ama bu şekilde setter fonksiyonu kullandığımda içerisine istediğim validasyonları koyabilirim. Örneğin exam1 değerine direk erişimde – (negatif) değerler verebilirken setter methodunda negatif değer geldiğinde bunu direk exam1 değerine eşitlemeden kullanıcıyı uyarabilirim veya hata fırlatabilirim. Hemen bir örnekle gösterelim;
Not : Hata fırlatmayı önceki derslerimizde görmüştük.
def setExam(self,newVal): if newVal<0 or newVal>100 : raise ValueError("Sınav puanı 0'dan küçük ve 100'den büyük bir değer olamaz ")
Setter fonksiyonumuzu yazdık şimdi programımızın tamamını görelim.
class RegisterCourse: def __init__(self): self.name = "Ahmet" self.surname = "Kaleli" self.__exam1 = 74 self.__exam2 = 80 self.__courses = [] def __add(self,course): self.courses.append(course) def getExam(self): return self.__exam1 def setExam(self,newVal): if newVal<0 or newVal>100 : raise ValueError("Sınav puanı 0'dan küçük ve 100'den büyük bir değer olamaz ") register = RegisterCourse() register.setExam(-10)
Şimdi çıktıya bakalım;
ValueError: Sınav puanı 0'dan küçük ve 100'den büyük bir değer olamaz
Biz burada sınav puanının 0’dan küçük ve 100’den büyük değer olma durumlarını kontrol etmiş olduk.
Mobilhanem.com da Python Eğitim serisinin Python Kapsülleme(Encapsulation) dersinin sonuna geldik. Bir sonraki derste Python Inheritance(Miras Alma ) konusu ile birlikte olacağız. Eksik yada yanlış gördüğün yerler için Soru-Cevap iletişime geçmekten çekinmeyin. Bir sonraki derste görüşmek üzere.
Tüm Dersler İçin Tıklayın
176
Hiç anlamadığım konuları sizin sade açık anlasilir kısa tam hedefe isabet anlatisinizla anladım.Gercekten çok güzel örneklerle apaçık anlatım yapmışsınız.O kitaplardaki ağdalı dile hiç gerek yok mükemmel bi sadelik. Tebrikler.
Tesekurler bir nebze faydamiz olduysa ne mutlu bize. Boyle guzel yorumlar alinca daha cok sevkleniyoruz yazmak icin 🙂
Harikasınız. Çok anlamlı bir örnek üzerinden herkesin anlayabileceği bir sadelikte anlatmışsınız. Teşekkür ederim. Çok faydalandım.
harika sade net bir anlatım. Teşekkürler. anlamadığım yerler yerine oturdu
yukarda setter metodu ekleyelimde tablonun altında ayrıyetten (register.setExam1(40)) die eklemissin ya onu tablodaki kodun neresine eklicez