Nesne Tabanlı Programlama -2- (OOP)

Gökhan YAVAŞ
gokhanyavas
Published in
3 min readDec 16, 2016

Programlama kavramları içerisinde, özellikle yeni başlayan kişilerin kafasında en fazla kafa karıştıran nesne kavramını inceleyeceğiz. Nesne (object), kavramının aslında o kadar da kafa karıştıracak bir şey olmadığını göreceksiniz. Nesne, Python’da belli bir takım metotlara, niteliklere sahip öğeleri tanımlamak için bir tabirdir.

Şimdi o aklınızı karıştıran şeyi tanımlayalım:

class FX:
pass
dolar = FX

İşte buradaki dolar = FX komutu ile bir nesne üretmiş olduk. Bu nesne, FX adlı sınıfın bütün nitelik ve metotlarını bünyesinde barındıran bir nesnedir.
Her şeyin bir nesne olduğunu duymuşsunuzdur. Gerçektende (if, else, len, gibi deyim ve işleçler hariç)her şey bir nesnedir.Sınıf ÜyeleriPython'da bir sınıfın içinde bulunan, fonksiyonlar, nitelikler, metotlar ve buna benzeyen başka veri tipleri, o sınıfın üyeleri meydana getirir. Bu sınıfın üyeleri 3 kısımda incelenir.
  1. Public Members (Açık Üyeler)
  2. Private Members (Özel Üyeler)
  3. Semi-Private Members(Yarı-Özel Üyeler)
Sırayla bu üyeleri inceleyelim.
Public Members (Açık Üyeler)
Bir sınıfın üyesi dışarıya açıksa, yani bu öğeye dışarıdan açıkça ulaşılabiliyorsa (normal yöntemlerle) bu üyelere, açık üyeler denir. Açık üyelere örnek olarak defter.py dosyamızı verebiliriz. Bu dosyamızdaki tüm fonksiyonlara açık bir biçimde eriştiğimizi hatırlayın.
Private Members (Özel Üyeler)
Özel üyeler, açık üyelerin aksine dışarıya açık değildirler. Özel üyelere, normal yöntemleri kullanarak sınıfın dışından erişemeyiz. Konuyu daha anlaşılır kılmak için defter.py dosyamızdaki sınıfı kullanarak devam edeceğiz.
class AdresDefteri:
'Adres Defteri Sınıfımız'
__kisiler = []
def __init__(self, isim):
self.isim = isim
self.numaralar = []
self.kisiEkle()
@classmethod
def kisiSayisiniGoster(cls):
print(len(cls.__kisiler))
def kisiEkle(self):
self.__kisiler.append(self.isim)
self.__kisiler.append(self.numaralar)
print("{},{} rehbere eklendi" .format(self.isim, self.numaralar))
def kisiyiGoruntule(self):
print("Kisi Listesi:")
for rehber in self.__kisiler:
print(rehber)
def numaraEkle(self, numaralar):
self.numaralar.append(numaralar)
def numaralariGoruntule(self):
print("{} isimli kisinin numaralari:".format(self.isim))
for numaralar in self.numaralar:
print(numaralar)
@staticmethod
def statikMetot():
print("merhaba, ben statik metot!")
Örneğimizdeki __kisiler isimli öğemizi özel üye olarak tanımladık. Python'da özel üyeler tanımlamak istersek değişkenimizin başında 2 adet alt çizgi __ veya yalnızca tek alt çizgi kullanırız. Başlarında alt çizgilerin bulunduğu öğeler özel üye demektir. Özel üyelere, açık üyelere eriştiğimiz gibi erişilmediğini bilin.
Semi-Private Members(Yarı-Özel Üyeler)
Yarı-Özel Üyeler, herhangi bir özel mekanizma tarafından korunan değil, sadece Python topluluğu tarafından oluşmuş geleneklerin korunan nitelikleridir. Sınıfımızdaki herhangi bir üyeyi yarı-özel üye olarak tanımlamak için yapmamız gereken başına alt çizgi _ eklemektir. Örneğin:
class GokhanYavas:_yari_ozel_uye = 'yari_ozel_uye'
Burada tanımladığımız _yari_ozel_uye adlı niteliğe sınıf içinden ve dışından erişmemizi sınırlayan hiçbir mekanizma bulunmaz. Sınıfın içinde tek alt çizgi ile başlayan bir öğe gördüğümüzde bunun sınıfın iç işleyişine ilişkin bir ayrıntı olduğunu, sınıf dışından bu öğeyi değiştirmeye kalkışmamız gerektiğini anlarız.

@property

Property, özellik, nitelik anlamlarına gelmektedir. Property dekoratörünün yaptığı en temel iş, bir metodu, nitelik gibi kullanılabilir hale getirmektir. Şimdi örneği inceleyelim:class Cern:
def __init__(self):
pass
@property
def surum(self):
return '2.1'
surum isimli metodu @property dekoratörü ile dekore ettik. Bu sayede surum isimli metodu nitelik haline getirdik. Bunu şu şekilde kullanabiliriz artık:
uygulama = Cern
uygulama.surum
Peki ama neden metodu niteliğe dönüşmek isteriz ki?Bir uygulama geliştirip içinde bazı kelimler kullandınız ve sürümleri geçtikçe bazı kelimelerin (hardisk kelimesi yerine = hdd) yerine farklı ifadeler kullansak daha iyi olacak gibi dediniz işte bu sırada @property dekoratörü devreye giriyor.class Hardware():
def __init__(self):
...
@property
def harddisk(self):
return self.hdd
Bu şekilde self.harddisk niteliğine yapılacak çağrılarda harddisk() adlı metot vasıtasıyla self.veri niteliğine yönlendirilecek. Bu yöntem sayesinde, yazılmış eski kodları bozmadan program üzerinde istenilen değişikliği yapmış oluruz. Yani geriye dönük uyumluluğu (backwards compatibility) sağlamış olduk.

@property dekoratörünün 3 önemli özelliği bulunmaktadır:

  • Değer Döndürmek
  • Değer Atamak
  • Değer Silmek
İlgili metoda ulaşmak için @property ile dekore edilir. İlgili niteliği @metot_isimi.setter şeklinde dekore ederek ayarlarız ve ilgili niteliği nasıl sileceğimizi ise @metot_isimi.deleter şeklinde dekore ederiz. Konumuzu bitirmeden @property dekoratörünün bu 3 özelliğini içeren örneğimizi inceleyim.class AdresDefteri:
'Adres Defteri Sınıfımız'
__kisiler = []
def __init__(self, isim):
self._isim = isim
self.numaralar = []
self.kisiEkle()
@classmethod
def kisiSayisiniGoster(cls):
print(len(cls.__kisiler))
def kisiEkle(self):
self.__kisiler.append(self.isim)
self.__kisiler.append(self.numaralar)
print("{},{} rehbere eklendi" .format(self._isim, self.numaralar))
def kisiyiGoruntule(self):
print("Kisi Listesi:")
for rehber in self.__kisiler:
print(rehber)
def numaraEkle(self, numaralar):
self.numaralar.append(numaralar)
def numaralariGoruntule(self):
print("{} isimli kisinin numaralari:".format(self.isim))
for numaralar in self.numaralar:
print(numaralar)

Şimdiye kadar kullanmış olduğumuz defter.py dosyamızı tekrar kullanacağız. Bahsettiğimiz bu 3 özelliği sınıfımıza ekleyelim:
@property
def isim(self):
return self._isim
@isim.setter
def isim(self, yeni_isim):
kisi = self.__kisiler.index(self.isim)
self.__kisiler[kisi] = yeni_isim
print('yeni isim: ', yeni_isim)
@isim.deleter
def isim(self):
del self._isim
Bu tanımladığımız metotlar ile konuya ait 3 önemli işlem gerçekleştirilir. Bir önceki anlatımdaki işlemleri tekrar ederek bir kaç kayıt girin ve girdiğiniz kayıtlar arasından bir kişinin adını değiştirin. Bu değiştirme işlemi için şu şekilde bir komut vermeniz gerekir:
k3.isim = 'Gokhan'buradaki k3'ün ne olduğunu biliyorsunuz... isim parametresi ise sınıfımız içinde tanımladığımız fonksiyondan geliyor ve yeni değeri tırnak içinde belirtip eski isimi değiştiriyoruz. Sınıfımız içindeki kişiyi görüntüle fonksiyonu ile rehberimizdeki kişileri görüntüleyebilir, yaptığınız işlemin gerçekleştiğini teyit edebilirsiniz . Öğrendiğimiz bu kısıma kadar OOP'de artık daha fazla (orta-ileri seviye) bildiginizi ifade edebilirsiniz.

--

--