OOP | Bölüm 5

Bu bölümde "magic method" dediğimiz özel/sihirli metotlardan bahsedeceğiz. Normalde çift alt tire (__) ile başlayan metotların özel metotlar olduğunu biliyorsunuz. Örneğin __init__, __name__ gibi. İşte, şimdi göreceğimiz bu iki magic method sırasıyla __str__ ve __repr__ şeklindedir.

Ufak bir örnek ile başlayalım.

name = "Cyber Worm" şeklinde bir şey tanımladım. Sonrasında sade bir şekilde print(name) ifadesini verdim. Son olarak aynı şeyi str() ile yazdırdım. Bu kullanımları önceki bloglardan biliyorsunuz. Ancak, arka planda gerçekten ne olduğunu hiç düşündünüz mü?

Bu sefer age = 23 şeklinde int bir değişken atadım. type(age) dediğimde bunun int sınıfına ait olduğunu söyledi. Sonrasında print(age) ve print(str(age)) dediğimde aynı çıktıyı sorunsuz bir şekilde gördüm. Şimdi, işin sırrını öğrenelim.

Biz, print(str()) dediğimiz zaman Python o class içerisindeki __str__ metoduna gidip bakıyor. __str__ metodu, bir ifadenin nasıl yazdırılacağına karar verir. Örneğin ben bu int değeri str() ile yazdırdığım için Python, print() class'ına gitti ve __str__ metodunun içine baktı. Oradaki __str__ metodunu bulduğunda ise girilen bu sayının metinsel bir ifade olarak yazdırılacağını anladı ve öyle yaptı.

Demek ki __str__ metodu, bir ifadenin ne şekilde olacağına karar veren bir metottur. İsterseniz bunun bir örneğini yapalım. Bunun için bir class oluşturacağım.

Bir class ve pc1 isimli bir instance oluşturdum. Bu noktada print(pc1) dediğim zaman karşıma değişik bir çıktı geldi. Bu aslında şunu diyor: "Bu bir objedir ve bu obje hafızada '0x00...' şuradadır". Demek ki Python bunun bir obje olduğunun farkında ama bunu nasıl yazdıracağını bilmiyor. Dolayısıyla bunu yazdırmak yerine bize bu işlem ile alakalı bazı bilgiler döndürüyor.

Peki, __str__ metoduna gelelim ve Python'a "Bunu böyle yazmalısın" diye ders verelim.

def __str__(self): şeklinde bir tanımlama yaptık ve içerisine, daha önce de yaptığımız gibi return ile döndürülecek ifadeyi verdik. print(pc1) dediğimizde her şeyin sorunsuz bir şekilde çalıştığını ve __str__ içerisinde tanımladığımız gibi bir çıktı geldiğini görüyorsunuz.

Normal şartlarda class içerisine bir metot tanımladığımızda o metodun çalışması için şöyle bir kullanım sağlıyorduk:

print(pc1.tellMe()) diyorduk ve işimizi hallediyorduk. Ancak dikkat ederseniz biraz önce print(pc1.__str__()) gibi bir şey yapmadık; direkt olarak print(pc1) dedik ve işimiz halloldu. Biraz önce, bir yazdırma işleminde Python'un aslında ilk önce __str__ fonksiyonuna baktığını söylemiştim. İşte, biz print(pc1) dediğimizde Python hemen ait olduğu class yapısına girip __str__ metoduna bakındı. Bulduğunda ise içerisinde nasıl bir tanımlama yapılmışsa ekrana o şekilde bir çıktı verdi.

İşte __str__(self): metodu bu şekilde. Şimdi, __repr__ metodunu inceleyelim.

Bunun için yine bir değişken tanımlaması yapalım.

print(str(name)) dediğimde normal bir şekilde çıktı aldık; Cyber Worm. Ancak aynı işi repr() ile yaptığımızda 'Cyber Worm' şeklinde bir çıktı geldi. Dikkat ederseniz bu çıktı, tırnak işaretleri arasında geldi ve bize bunun bir string olduğunu vurguluyor gibi duruyor. Daha spesifik sonuçları olan bir örnek verelim.

Daha önceden bildiğiniz modülü kullanarak bugünün tarihini yazdırdım. Bu noktada print(str(t)) dediğim zaman normal bir şekilde tarihi yazdırdığını görüyorsunuz. Ancak aynı yazdırma işlemini repr() ile yaptığımda daha farklı bir sonuç çıktı; datetime.date(2022, 12, 27). Yani bize, bu sonucun datetime modülüne ait olduğunu, date metodunu kullandığını ve verilen parametreleri yazdırıyor.

Demek ki repr() metodu yalnızca geliştiriciler yani bizler için tasarlanmıştır. Bu, daha çok hata ayıklama (debugging) için kullanılan bir metottur. Bize, detaylı bir çıktı verdiği için hatanın nereden kaynaklandığını bulmamızı kolaylaştırır. Aynı şeyi sıradan bir kullanıcıya gösterirseniz pek bir şey anlamayacaktır ama biz, neyin nereden geldiğini, hangi argümanları aldığını da görebiliyoruz. İşte, repr() metodu da bu şekilde.

Biraz önce dediğim gibi Python, ilk önce __str__ metodunu arar. Eğer __str__ metodu o class içerisinde yoksa __repr__ metodunu arayacaktır. Bunu bir örnekle görelim.

Bunun için az önce tanımladığım sınıfı tekrar tanımlıyorum ve içerisine __repr__ metodunu ekliyorum.

Gördüğünüz üzere __repr__ metodunu ekledim ama çalışmadı. Çünkü class içerisinde __str__ metodu mevcut. Python'un her şeyden önce __str__ metoduna baktığını artık biliyorsunuz. Peki, __str__ metodunu yorum satırı durumuna yani çalıştırılmayacak hâle getirelim ve tekrar deneyelim.

__str__ metodunu yorum satırına alıp kodu çalıştırınca __repr__ metodunun çalıştığını göreceksinizdir. Python __str__ için sınıfın içine baktı ama bulamadığında __repr__ çalıştı. Hatta dikkat ederseniz print(pc1.__repr__()) demedim. Buna rağmen çalıştı.

Peki, diyelim ki hem __str__ hem de _repr__ metotlarını çalıştıracaksınız. Bunu nasıl yapardınız?

Özel olarak __repr__ çalışsın istiyorsanız kendisini çağırmanız gerekir. Bunun için print(pc1.__repr__()) şeklinde bir kullanım sağlayabilirsiniz.

__str__() ve __repr__() isimli magic method yapılarını inceledik. Bir sonraki bölümde görüşmek üzere.


Yayınlanma Tarihi: 2022-12-27 12:01:16

Son Düzenleme Tarihi: 2022-12-30 15:19:50