Nesne Tabanlı Programlama (Devamı)

Nesne tabanlı programlamaya ilişkin bu son bölümde önceki derslerde incelemeye fırsat bulamadığımız ileri düzey konulardan söz edeceğiz.

İnşa, İlklendirme ve Sonlandırma

Python’da bir sınıfın ömrü üç aşamadan oluşur:

  1. İnşa (Construction)

  2. İlklendirme (initialization)

  3. Sonlandırma (destruction)

Biz bundan önceki derslerimizde ilklendirme sürecinin nasıl yürüdüğünü görmüştük. Bu dersimizde ise, ilklendirme sürecine de tekrar değinmekle birlikte, özellikle inşa ve sonlandırma süreçlerini ele alacağız.

Önceki derslerimizden de bildiğimiz gibi, Python’da bir sınıfı ilklendirmek için __init__() adlı bir metottan yararlanıyoruz. Ancak, adının aksine, ilklendirme, sınıfların oluşturulmasına ilişkin ilk basamak değildir. Python, bir sınıfın ilklendirilmesinden önce o sınıfı inşa eder. Bu inşa işleminden sorumlu metodun adı ise __new__()’dur. Gelin bu metodu yakından tanımaya çalışalım.

__new__() Metodu

Bildiğiniz gibi, Python’da basit bir sınıfı şu şekilde tanımlıyoruz:

class Sınıf():
    def __init__(self):
        print('merhaba sınıf!')

Burada __init__() metodu, sınıfımız örneklenir örneklenmez hangi işlemlerin yapılacağını gösteriyor. Yani mesela sınıf = Sınıf() gibi bir kod yardımıyla Sınıf() adlı sınıfı örneklediğimiz anda ne olacağını bu __init__() metodu içinde tanımlıyoruz:

>>> # Yukarıdaki kodların `sınıf.py` adlı bir dosyada olduğunu varsayalım
>>> import sınıf
>>> snf = sınıf.Sınıf()

merhaba sınıf!

Gördüğünüz gibi, tam da __init__() metodunda tanımladığımız şekilde, sınıfımızı örneklediğimiz anda ekrana ‘merhaba sınıf’ çıktısı verildi.

Ancak yukarıda da belirttiğimiz gibi, bir sınıf örneklendiğinde çalışan ilk metot aslında __init__() değildir. Python bu süreçte alttan alta __new__() adlı başka bir metodu çalıştırır. Gelin bunu kanıtlayalım:

class Sınıf():
    def __new__(cls):
        pass

    def __init__(self):
        print('merhaba sınıf')

Bu sınıfı örneklediğinizde, bir önceki kodların aksine, ekrana ‘merhaba sınıf’ yazısı çıktı olarak verilmeyecektir. İşte bunun sebebi, Python’ın öntanımlı __new__() metodunun üzerine yazıp, o metodun işlevselliğini ortadan kaldırmış olmanızdır. Eğer __new__() metodunun öntanımlı davranışını taklit etmek isterseniz yukarıdaki kodları şu şekilde yazmalısınız:

class Sınıf():
    def __new__(cls, *args, **kwargs):
        return object.__new__(cls, *args, **kwargs)

    def __init__(self):
        print('merhaba sınıf')

Burada yaptığımız şeyin aslında temel olarak basit bir miras alma işleminden ibaret olduğunu görüyor olmalısınız. Bildiğiniz gibi, Python’daki bütün sınıflar, eğer başka bir sınıfı miras olarak almıyorlarsa, otomatik olarak object sınıfını miras alırlar. Yani aslında yukarıdaki sınıf tanımını Python şöyle görür:

class Sınıf(object):
    ...

Burada object taban sınıf olmuş oluyor. Bu taban sınıfın __new__() metodunun sahip olduğu işlevselliği Sınıf adlı alt sınıfa aktarabilmek için taban sınıfı kendi __new__() metodumuz içinde çağırıyoruz:

class Sınıf():
    def __new__(cls, *args, **kwargs):
        return object.__new__(cls, *args, **kwargs)

İşte eğer bir sınıfın inşa edilme sürecinin nasıl işleyeceğini kontrol etmek isterseniz bu __new__() metodunun üzerine yazarak metodu değişikliğe uğratabilirsiniz:

class Sınıf():
    def __new__(cls, *args, **kwargs):
        print('Yeni sınıf inşa edilirken lütfen bekleyiniz...')
        return object.__new__(cls, *args, **kwargs)

    def __init__(self):
        print('merhaba sınıf')

Ancak bu noktada şunu belirtmeden de geçmeyelim. __new__() metodu, sık sık muhatap olmanız gereken bir metot değil. __new__() metodunu kullanarak yapacağınız pek çok şeyi aslında doğrudan __init__() metodu aracılığıyla da yapabilirsiniz.

Yorumlar

Önemli Not

Sorularınızı yorumlarda dile getirmek yerine Yazbel Forumunda sorarsanız çok daha hızlı cevap alabilirsiniz.
Belgelerdeki bir hata veya eksiği dile getirecekseniz lütfen yorumları kullanmak yerine Github'da bir konu (issue) açın.
Eğer yazdığınız yorum içinde kod kullanacaksanız kodlarınızı <pre><code> etiketleri içine alın. Örneğin:
        <pre><code class="python">
        print("Merhaba Dünya!")
        </code></pre>