Bu yazımızda çok önemli bir konuyu işlemeye başlayacağız: Python’da “Nesne Tabanlı Programlama” (Object Oriented Programming). Yabancılar bu ifadeyi “OOP” olarak kısaltıyor. Gelin isterseniz biz de bunu Türkçe’de NTP olarak kısaltalım… Şimdilik bu “Nesne Tabanlı Programlama”nın ne olduğu ve tanımı bizi ilgilendirmiyor. Biz şimdilik işin teorisiyle pek uğraşmayıp pratiğine bakacağız. NTP’nin pratikte nasıl işlediğini anlarsak, teorisini araştırıp öğrenmek de daha kolay olacaktır. Neden Nesne Tabanlı Programlama? İsterseniz önce kendimizi biraz yüreklendirip cesaretlendirelim. Şu soruyu soralım kendimize: Nesne Tabanlı Programlama'ya hiç girmesem olmaz mı? Bu soruyu cevaplandırmadan önce bakış açımızı şöyle belirleyelim. Daha doğrusu bu soruyu iki farklı açıdan inceleyelim: NTP'yi öğrenmek ve NTP'yi kullanmak... Eğer yukarıdaki soruya, "NTP'yi kullanmak" penceresinden bakarsak, cevabımız, "Evet," olacaktır. Yani, "Evet, NTP'yi kullanmak zorunda değilsiniz". Bu bakımdan NTP'yle ilgilenmek istemeyebilirsiniz, çünkü Python başka bazı dillerin aksine NTP'yi dayatmaz. İyi bir Python programcısı olmak için NTP'yi kullanmasanız da olur. NTP'yi kullanmadan da gayet başarılı programlar yazabilirsiniz. Bu bakımdan önünüzde bir engel yok. Ama eğer yukarıdaki soruya "NTP'yi öğrenmek" penceresinden bakarsak, cevabımız, "Hayır", olacaktır. Yani, "Hayır, NTP'yi öğrenmek zorundasınız!". Bu bakımdan NTP'yle ilgilenmeniz gerekir, çünkü siz NTP'yi kullanmasanız da başkaları bunu kullanıyor. Dolayısıyla, NTP'nin bütün erdemlerini bir kenara bıraksak dahi, sırf başkalarının yazdığı kodları anlayabilmek için bile olsa, elinizi NTP'yle kirletmeniz gerekecektir... Bir de şöyle düşünün: Gerek internet üzerinde olsun, gerekse basılı yayınlarda olsun, Python'a ilişkin pek çok kaynakta kodlar bir noktadan sonra NTP yapısı içinde işlenmektedir. Bu yüzden özellikle başlangıç seviyesini geçtikten sonra karşınıza çıkacak olan kodları anlayabilmek için bile NTP'ye bir aşinalığınızın olması gerekir. Dolayısıyla en başta sorduğumuz soruya karşılık ben de size şu soruyu sormak isterim: "Daha nereye kadar kaçacaksınız bu NTP'den?" Dikkat ederseniz, bildik anlamda NTP'nin faydalarından, bize getirdiği kolaylıklardan hiç bahsetmiyoruz. Zira şu anda içinde bulunduğumuz noktada bunları bilmenin bize pek faydası dokunmayacaktır. Çünkü daha NTP'nin ne olduğunu dahi bilmiyoruz ki cicili bicili cümlelerle bize anlatılacak "faydaları" özümseyebilelim... NTP'yi öğrenmeye çalışan birine birkaç sayfa boyunca "NTP şöyle iyidir, NTP böyle hoştur," demenin pek faydası olmayacaktır. Çünkü böyle bir çaba, konuyu anlatan kişiyi ister istemez okurun henüz bilmediği kavramları kullanarak bazı şeyleri açıklamaya çalışmaya itecektir. Bu da okurun zihninde birtakım fantastik cümlelerin uçuşmasından başka bir işe yaramayacaktır. Dolayısıyla, NTP'nin faydalarını size burada bir çırpıda saymak yerine, öğrenme sürecine bırakıyoruz bu "özümseme" işini... NTP'yi öğrendikten sonra, bu programlama tekniğinin Python deneyiminize ne tür bir katkı sağlayacağını, size ne gibi bir fayda getireceğini kendi gözlerinizle göreceksiniz. En azından biz bu noktada şunu rahatlıkla söyleyebiliriz: NTP'yi öğrendiğinizde Python Programlama'da bir anlamda "boyut atlamış" olacaksınız. Sonunda özgüveniniz artacak, orada burada Python'a ilişkin okuduğunuz şeyler zihninizde daha anlamlı izler bırakmaya başlayacaktır. Sınıflar NTP’de en önemli kavram “sınıflar”dır. Zaten NTP denince ilk akla gelen şey de genellikle “sınıflar” olmaktadır. Sınıflar yapı olarak “fonksiyonlara” benzetilebilir. Hatırlarsanız, fonksiyonlar yardımıyla farklı değişkenleri ve veri tiplerini, tekrar kullanılmak üzere bir yerde toplayabiliyorduk. İşte sınıflar yardımıyla da farklı fonksiyonları, veri tiplerini, değişkenleri, metotları gruplandırabiliyoruz. Sınıf Tanımlamak Öncelikle bir sınıfı nasıl tanımlayacağımıza bakmamız gerekiyor. Hemen, bir sınıfı nasıl tanımlayacağımızı bir örnekle görmeye çalışalım: Python’da bir sınıf oluşturmak için şu yapıyı kullanıyoruz: class IlkSinif: Böylece sınıfları oluşturmak için ilk adımı atmış olduk. Burada dikkat etmemiz gereken bazı noktalar var: – Hatırlarsanız fonksiyonları tanımlarken “def” parçacığından yararlanıyorduk. Mesela: def deneme(): – Sınıfları tanımlarken ise “class” parçacığından faydalanıyoruz: class IlkSinif: Tıpkı fonksiyonlarda olduğu gibi, isim olarak herhangi bir kelimeyi seçebiliriz. Mesela yukarıdaki fonksiyonda “deneme” adını seçmiştik. Yine yukarıda gördüğümüz sınıf örneğinde de “IlkSinif” adını kullandık. Tabii isim belirlerken Türkçe karakter kullanamıyoruz… – Sınıf adlarını belirlerken kullanacağımız kelimenin büyük harf veya küçük harf olması önemli değildir. Ama seçilen kelimelerin ilk harflerini büyük yazmak adettendir. Mesela "class Sinif" veya "class HerhangiBirKelime". Gördüğünüz gibi sınıf adı birden fazla kelimeden oluşuyorsa her kelimenin ilk harfi büyük yazılıyor. Bu bir kural değildir, ama her zaman adetlere uymak yerinde bir davranış olacaktır... – Son olarak, sınıfımızı tanımladıktan sonra parantez işareti kullanmak zorunda olmadığımıza dikkat edin. En azından şimdilik... Bu parantez meselesine tekrar döneceğiz. İlk adımı attığımıza göre ilerleyebiliriz: class IlkSinif: mesele = "Olmak ya da olmamak" Böylece eksiksiz bir sınıf tanımlamış olduk. Aslında tabii ki normalde sınıflar bundan biraz daha karmaşıktır. Ancak yukarıdaki örnek, gerçek hayatta bu haliyle karşımıza çıkmayacak da olsa, hem yapı olarak kurallara uygun bir sınıftır, hem de bize sınıflara ilişkin pek çok önemli ipucu vermektedir. Sırasıyla bakalım: - İlk satırda doğru bir şekilde sınıfımızı tanımladık. - İkinci satırda ise “mesele” adlı bir değişken oluşturduk. Böylece ilk sınıfımızı başarıyla tanımlamış olduk. Sınıfları Çalıştırmak Şimdi güzel güzel yazdığımız bu sınıfı nasıl çalıştıracağımıza bakalım: Herhangi bir Python programını nasıl çalıştırıyorsak sınıfları da öyle çalıştırabiliriz. Yani pek çok farklı yöntem kullanabiliriz. Örneğin yazdığımız şey arayüzü olan bir Tkinter programıysa "python programadı.py" komutuyla bunu çalıştırabilir, yazdığımız arayüzü görebiliriz. Hatta gerekli ayarlamaları yaptıktan sonra programın simgesine çift tıklayarak veya GNU/Linux sistemlerinde konsol ekranında programın sadece adını yazarak çalıştırabiliriz programımızı. Eğer komut satırından çalışan bir uygulama yazdıysak, yine "python programadı.py" komutuyla programımızı çalıştırıp konsol üzerinden yönetebiliriz. Ancak bizim şimdilik yazdığımız kodun bir arayüzü yok. Üstelik bu sadece NTP'yi öğrenmek için yazdığımız, tam olmayan bir kod parçasından ibaret. Dolayısıyla sınıfımızı tecrübe etmek için biz şimdilik doğrudan Python komut satırı içinden çalışacağız. Şu halde herkes kendi platformuna uygun şekilde Python komut satırını başlatsın! Python'u başlattıktan sonra bütün platformlarda şu komutu vererek bu kod parçasını çalıştırılabilir duruma getirebiliriz: >>>from sinif import * Burada sizin bu kodları “sinif.py” adlı bir dosyaya kaydettiğinizi varsaydım. Dolayısıyla bu şekilde dosyamızı bir modül olarak içe aktarabiliyoruz (import). Bu arada Python'un bu modülü düzgün olarak içe aktarabilmesi için komut satırını, bu modülün bulunduğu dizin içinde açmak gerekir. Python içe aktarılacak modülleri ararken ilk olarak o anda içinde bulunulan dizine bakacağı için modülümüzü rahatlıkla bulabilecektir. GNU/Linux kullanıcıları komut satırıyla daha içli dışlı oldukları için etkileşimli kabuğu modülün bulunduğu dizinde nasıl açacaklarını zaten biliyorlardır... Ama biz yine de hızlıca üzerinden geçelim...(Modülün masaüstünde olduğunu varsayıyoruz): ALT+F2 tuşlarına basıp açılan pencereye "konsole" (KDE) veya "gnome-terminal" (GNOME) yazıyoruz. Ardından konsol ekranında "cd Desktop" komutunu vererek masaüstüne erişiyoruz. Windows kullanıcılarının komut satırına daha az aşina olduğunu varsayarak biraz daha detaylı anlatalım bu işlemi... Windows kullanıcıları ise Python komut satırını modülün olduğu dizin içinde açmak için şu yolu izleyebilir (yine modülün masaüstünde olduğunu varsayarsak...): Başlat > Çalıştır yolunu takip edip açılan kutuya "cmd" yazıyoruz (parantezler olmadan). Komut ekranı karşımıza gelecek. Muhtemelen içinde bulunduğunuz dizin "C:\********s and Settings\İsminiz" olacaktır. Orada şu komutu vererek masaüstüne geçiyoruz: cd Desktop Şimdi de şu komutu vererek Python komut satırını başlatıyoruz: C:/python25/python Tabii kullandığınız Python sürümünün 2.5 olduğunu varsaydım. Sizde sürüm farklıysa komutu ona göre değiştirmelisiniz. Eğer herhangi bir hata yapmadıysanız karşınıza şuna benzer bir ekran gelmeli: C:\********s and Settings\Isminiz>c:/python25/Python Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> Şimdi bu ekrandaki ">>>" satırından hemen sonra şu komutu verebiliriz: from sinif import * Artık sınıfımızı çalıştırmamızın önünde hiç bir engel kalmadı sayılır. Bu noktada yapmamız gereken tek bir işlem var: Örnekleme Örnekleme (Instantiation) Şimdi şöyle bir şey yazıyoruz: >>>deneme = IlkSinif() Böylece oluşturduğumuz sınıfı bir değişkene atadık. NTP kavramlarıyla konuşacak olursak, “sınıfımızı örneklemiş olduk”. Peki bu "örnekleme" denen şey de ne oluyor? Hemen bakalım: İngilizce’de “instantiation” olarak ifade edilen “örnekleme” kavramı sayesinde sınıfımızı kullanırken belli bir kolaylık sağlamış oluyoruz. Gördüğünüz gibi, “örnekleme” (instantiation) aslında şekil olarak yalnızca bir değişken atama işleminden ibarettir. Nasıl daha önce gördüğümüz değişkenler uzun ifadeleri kısaca adlandırmamızı sağlıyorsa, burada da “örnekleme” işlemi hemen hemen aynı vazifeyi görüyor. Yani böylece ilk satırda tanımladığımız sınıfa daha kullanışlı bir isim vermiş oluyoruz. Dediğimiz gibi, bu işleme “örnekleme” (instantiation) adı veriliyor. Bu örneklemelerin her birine ise “örnek” (instance) deniyor. Yani, IlkSinif adlı sınıfa bir isim verme işlemine “örnekleme” denirken, bu işlem sonucu ortaya çıkan değişkene de, “örnek” (instance) diyoruz. Buna göre, burada “deneme” adlı değişken, “IlkSinif” adlı sınıfın bir örneğidir (“deneme” is an instance of the class “IlkSinif”). Daha soyut bir ifadeyle, örnekleme işlemi “Class” (sınıf) nesnesini etkinleştirmeye yarar. Yani sınıfın bütününü alır ve onu paketleyip, istediğimiz şekilde kullanabileceğimiz bir nesne haline getirir. Şöyle de diyebiliriz: Biz bir sınıf tanımlıyoruz. Bu sınıfın içinde birtakım değişkenler, fonksiyonlar, vb. olacaktır. Hayli kaba bir benzetme olacak ama, biz bunları bir internet sayfasının içeriğine benzetebiliriz. İşte biz bu sınıfı "örneklediğimiz" zaman, sınıf içeriğini bir bakıma erişilebilir hale getirmiş oluyoruz. Tıpkı bir internet sayfasının, "www...." şeklinde gösterilen adresi gibi... Mesela www.python.quotaless.com adresi içindeki bütün bilgileri bir sınıf olarak düşünürsek, "www.python.quotaless.com" ifadesi bu sınıfın bir örneğidir... Durum tam olarak böyle olmasa bile, bu benzetme, "örnekleme" işlemine ilişkin en azından zihnimizde bir kıvılcım çakmasını sağlayabilir. Daha yerinde bir benzetme şöyle olabilir: "İnsan"ı büyük bir sınıf olarak kabul edelim. İşte "siz" (yani Ahmet, Mehmet, vb...) bu büyük sınıfın bir örneği, yani ete kemiğe bürünmüş hali oluyorsunuz... Buna göre "insan" sınıfı insanın ne tür özellikleri olduğuna dair tanımlar (fonksiyonlar, veriler) içeriyor. "Mehmet" örneği (instance) ise bu tanımları, nitelikleri, özellikleri taşıyan bir "nesne" oluyor... alıntı
