Polimorfizm, farklı sınıflardan nesnelerin aynı metot çağrısıyla, aynı döngüde ya da aynı fonksiyonda kullanılabilmesidir. Örneğin bir e-posta nesnesinde de bir SMS nesnesinde de send() metodu varsa ikisini de send() ile çağırırsınız ve her biri mesajı kendi yoluyla gönderir. Python’da bunun için iki sınıfın ortak bir üst sınıftan türemesi her zaman gerekmez. Nesnede gereken metot varsa onu kullanabilirsiniz. Nesnenin sınıfına değil, hangi metotları olduğuna bakan bu yaklaşıma duck typing denir.
Bu bölümün kapsamı
NoteSınavda sorulur
Aynı metot çağrısının farklı nesnelerde farklı iş yapması
Ortak üst sınıf olmadan polimorfizm (duck typing)
Her yeni türde uzayan tür koşulu zincirinin neden kod kokusu sayıldığı
isinstance() kullanımının yerinde olduğu durumlar
hasattr() sonucunun neyi söyleyip söylemediği
EAFP ile LBYL yaklaşımlarının farkı ve yalnız beklenen istisnayı yakalamak
Polimorfizm ile kalıtımın farkı
NoteSınav dışı (bilgi amaçlı)
Soyut temel sınıf (ABC) ve @abstractmethod yazımı
typing.Protocol ile yapısal alt tipleme
Çoklu gönderim (multiple dispatch)
Bu başlıklar konunun devamıdır; ileride karşınıza çıkar ama bu derste ezberlemeniz beklenmiyor.
Çağıran kodun nesnenin türünü bilmesi gerekir mi?
Bir fonksiyon gelen nesnenin türüne bakıp ne yapacağını if type(x) is ... ile seçiyorsa, her yeni tür için bu zincire bir elif daha eklenir. Bu, işin yanlış yerde seçildiğini gösterir: mesajın nasıl gönderileceğini nesnenin kendisi bilmelidir. Böyle işaretlere kod kokusu (code smell) denir. Kod çalışır ama tasarımda bir sorun olduğunu gösterir. Python’da bunu düzeltmek için ortak bir üst sınıf şart değildir; nesnelerde aynı adlı metodun bulunması yeter.
Yukarıdaki iki sınıf ortak bir üst sınıftan türemiyor. Yine de ikisinde de send(message) metodu olduğu için aynı döngüde kullanılabildiler.
Duck typing
Nesnenin hangi sınıftan olduğuna değil, gereken metodu olup olmadığına bakın.
Duck typing’in kuralı budur.
Uyarı işareti: uzayan tür zinciri
def send_notification(notification, message):iftype(notification) is EmailNotification:return notification.send_email(message)eliftype(notification) is SmsNotification:return notification.send_sms(message)
Her yeni bildirim türünde bu fonksiyona bir elif eklemek gerekir. Bütün sınıflarda aynı adlı send() metodu olursa fonksiyon tek satıra iner ve yeni bir tür eklemek için onu değiştirmeniz gerekmez:
Importantisinstance() kullanmak başlı başına hata değildir
Tür kontrolü bazı yerlerde yerindedir: programa dışarıdan gelen verinin beklenen türde olup olmadığını denetlerken (sınır doğrulaması), bir nesneyi dosyaya ya da ağa yazmak için metne çevirirken (serileştirme) ya da karar gerçekten türe bağlıysa. Kod kokusu, nesnenin kendi metodunu çağırmak yerine her yeni türde uzayan bir koşul zinciriyle ne yapılacağını seçmektir.
hasattr() ne söyler, ne söylemez?
Bir nesnede belirli bir adda nitelik ya da metot bulunup bulunmadığını hasattr() ile kontrol edebiliriz:
Ancak hasattr(obj, "send") yalnızca nesnede send adında bir şey bulunduğunu söyler. Bunun çağrılabilir bir metot mu yoksa sıradan bir nitelik mi olduğunu, message parametresini alıp almadığını ya da gerçekten mesaj gönderip göndermediğini söylemez. Örneğin obj.send = "evet" atanmış bir nesnede de hasattr(obj, "send")True verir. Bu yüzden duck typing’i “önce her şeyi hasattr ile kontrol et” diye anlamayın.
EAFP ve LBYL
Python kodunda iki yaklaşımın adını sık görebilirsiniz:
LBYL (Look Before You Leap, “atlamadan önce bak”): İşi yapmadan önce koşulu kontrol edin.
EAFP (Easier to Ask Forgiveness than Permission, “özür dilemek izin istemekten kolaydır”): İşi doğrudan yapmayı deneyin. Beklediğiniz hata çıkarsa onu uygun except ile yakalayın.
Örneğin LBYL:
ifhasattr(notification, "send"): result = notification.send(message)else: result ="Desteklenmiyor"
EAFP yaklaşımı:
try: result = notification.send(message)exceptAttributeError: result ="Desteklenmiyor"
WarningEAFP “her şeyi except Exception ile yakala” değildir
Yalnızca beklediğiniz hata türünü yakalayın. Burada bir tuzak daha var: AttributeError bazen send() metodunun içinde de oluşabilir, örneğin metodun içinde bir nitelik adını yanlış yazdıysanız. Bunu körlemesine yakalarsanız kendi programlama hatanızı “desteklenmiyor” diye yorumlayabilirsiniz. Her bildirim nesnesinde send() bulunacağı baştan belliyse çoğu zaman en sade çözüm metodu doğrudan çağırmaktır.
Bu iki yaklaşımda 5. haftada gördüğünüz try/except bilgisini nesnelerin metotlarına uyguluyorsunuz. Hangisinin her zaman doğru olduğunu söyleyen bir kural yok. Bir yanda gereksiz ön kontrollerle uzayan kod, öbür yanda gerçek hataları da yutan geniş bir except var. İkisinin arasındaki dengeyi gözetin.
Davranış sözleşmesi
Duck typing’de de kurallar vardır. send(message) gibi ortak bir metodun ne aldığı, ne döndürdüğü ve hangi durumda hangi hatayı yükselttiği belli olmalıdır. Örneğin bu bölümdeki bütün bildirim sınıflarında send() bir metin alır ve bir metin döndürür. Bu kuralları yazan ayrı bir sınıf olmasa bile kuralların kendisi bir davranış sözleşmesidir: çağıran kod bu kurallara güvenerek yazılır.
Fonksiyonlar da polimorfik davranabilir
len() metinle, listeyle ve sözlükle aynı biçimde çalışır, çünkü üç türde de uzunluğu veren __len__ adlı özel bir metot vardır. len(x) yazdığınızda Python nesnenin __len__() metodunu çağırır. Bir işlemin çalışması için nesnede bulunması gereken metotlara protokol denir. 12. haftada kendi sınıflarınıza bu tür özel metotlar yazıp onları print() ve == gibi Python işlemleriyle çalıştıracaksınız.
Polimorfizm ve kalıtım ayrımı
Kalıtım iki sınıf arasındaki bir ilişkidir: class SmsNotification(Notification) yazdığınızda SmsNotification üst sınıfın metotlarını devralır. Polimorfizm ise farklı nesnelerin aynı metot çağrısıyla kullanılabilmesidir. Kalıtım polimorfizmi kolaylaştırabilir. Ama Python’da ortak üst sınıf zorunlu değildir; bu bölümün ilk örneğinde kalıtım yoktu.
Tanımanız yeterli: soyut temel sınıf (ABC)
from abc import ABC, abstractmethodclass Payment(ABC):@abstractmethoddef pay(self, amount):pass
ABC ile alt sınıfların hangi metotları yazması gerektiğini kodda açıkça belirtirsiniz: buradaki Payment sınıfından türeyen her sınıfta bir pay() metodu olmalıdır. ABC yazmak sınavda sorulmaz.
Alıştırma: Koşul zincirini kaldır
Tür kontrollerini kaldırın: döngü yalnızca animal.speak() çağırsın ve çıktı aynı kalsın. Ardından bir Bird sınıfı ekleyin ve döngüye dokunmadan onun da çalıştığını gösterin.
Alıştırma: Ortak davranışı tamamla
return payment.pay(amount)
Sıra sizde: Rapor çıktıları
ConsoleReport, TextReport ve CompactReport sınıflarının her birine bir render(data) metodu yazın. Tek bir show_report(report, data) fonksiyonuyla üçünü de kullanın. Dördüncü bir rapor sınıfı ekleyin ve show_report() fonksiyonunu değiştirmeden onunla da çalıştığını gösterin.
Çalışır kod görevi: Dört rapor nesnesini bir listeye koyun, döngüyle dolaşıp her birinin render() sonucunu yazdırın. Ayrıca bir nesnede hasattr(..., "render") sonucuna bakın. Sonra çözümünüzün neden tür ya da nitelik kontrol eden bir if zincirine ihtiyaç duymadığını iki cümleyle açıklayın.
Sınav provası
Önce kendi cevabınızı seçin; sonra cevap anahtarında her şıkkın neden doğru veya yanlış olduğunu okuyun. Çeldiriciler uydurma değil, bu konuda gerçekten yapılan hatalardır. Sınav maddeleri de bu mantıkla yazılır.
Madde 1. Aşağıdaki program ne yazdırır?
class EmailNotification:def send(self, message):returnf"E-posta: {message}"class SmsNotification:def send(self, message):returnf"SMS: {message}"for notification in [EmailNotification(), SmsNotification()]:print(notification.send("Merhaba"))
A.TypeError; farklı türler aynı listede tutulamaz
B.E-posta: Merhaba ve SMS: Merhaba
C. Hiçbir şey yazmaz
D. İki satırda da E-posta: Merhaba
E.AttributeError; iki sınıfın ortak üst sınıfı yoktur
Madde 2.EmailNotification ve SmsNotification ortak bir üst sınıftan türemedikleri hâlde aynı döngüde kullanılabiliyor. Bunun nedeni nedir?
A. Python’un örtük olarak ortak bir üst sınıf oluşturması
B. Metot adlarının aynı olması hâlinde Python’ın sınıfları birleştirmesi
C. Duck typing; çağrı için yalnız gereken metodun bulunması yeter
D.isinstance() denetiminin listede kendiliğinden yapılması
E. İki sınıfın da object sınıfından türemesi
Madde 3. Duck typing “her şeyi dene, çalışırsa olur” demek midir?
A. Hayır; ortak metodun ne alıp ne döndürdüğü yine belli olmalıdır
B. Evet; Python’da sözleşme kavramı yoktur
C. Evet; hasattr kontrolü yapıldığı sürece her şey denenebilir
D. Hayır; duck typing yalnızca kalıtım varken çalışır
E. Hayır; duck typing için soyut temel sınıf (ABC) kullanmak zorunludur
Madde 4. Aşağıdaki fonksiyonun tasarım sorunu nedir?
def send_notification(notification, message):iftype(notification) is EmailNotification:return notification.send_email(message)eliftype(notification) is SmsNotification:return notification.send_sms(message)
A. Sorun yoktur; tür denetimi her zaman en güvenli yoldur
B.type() sonucu is ile karşılaştırılamadığı için dallar çalışmaz
C. Her yeni bildirim türü bu fonksiyona bir elif daha ekletir
D.elif yerine else yazılırsa zincir kısalır ve sorun çözülür
E. Fonksiyon hem nesneyi hem mesajı parametre olarak aldığı için
Madde 5. Yukarıdaki koşul zincirini kaldırmak için ne yapılmalıdır?
A. Her tür için ayrı fonksiyon yazmak
B. Her sınıfa send(message) metodu yazıp onu doğrudan çağırmak
C.type() yerine isinstance() yazmak
D. Bütün bildirim türlerini tek bir sınıfta birleştirmek
E. Koşul zinciri yerine her türü bir fonksiyonla eşleyen bir sözlük kullanmak
Madde 6.isinstance() kullanımı ne zaman yerindedir?
A. Yalnızca hasattr() ile birlikte kullanıldığında
B. Hiçbir zaman; nesne tabanlı kodda tür kontrolü yasaktır
C. Yalnızca kalıtım kullanılmayan tasarımlarda
D. Karar gerçekten türe bağlıyken, örneğin dış veriyi doğrularken
E. Her metot çağrısından önce, nesne yanlış türdeyse erken durmak için
Madde 7.hasattr(obj, "send") çağrısı True verirse ne kesin olarak bilinir?
A.send(message) çağrısının hiçbir durumda hata vermeyeceği
B. Nesnenin send metodunu tanımlayan sınıftan türediği
C.send metodunun çağrıldığında bir metin döndüreceği
D.send metodunun çağrılınca beklenen işi yapacağı
E. Nesnede send adında bir nitelik ya da metot bulunduğu
Madde 8. EAFP ve LBYL yaklaşımları nasıl tanımlanır?
A. EAFP yalnızca dosya işlemlerinde, LBYL yalnızca nesnelerde kullanılır
B. İkisi de aynı şeyin farklı adıdır
C. EAFP her hatayı except Exception ile yakalamaktır
D. LBYL istisnaları hiç kullanmamaktır
E. LBYL önce koşulu denetler; EAFP işi dener, hatayı except ile yakalar
Madde 9.try: result = notification.send(message) / except AttributeError: kalıbının gözden kaçan riski nedir?
A.send() içindeki bir AttributeError da yakalanıp yanlış yorumlanır
B.except AttributeError çok dar olduğu için çoğu hatayı kaçırır
C. EAFP yaklaşımı Python’da önerilmez
D.as error yazılmadığı için hata mesajı kaybolur
E.try bloğu içinde atama yapılamaz
Madde 10. Polimorfizm ile kalıtım arasındaki ilişki nedir?
A. Polimorfizm, kalıtımın metot düzeyindeki başka bir adıdır
B. Kalıtım yalnızca polimorfizm için kullanılır
C. İkisi birbirinin alternatifidir; biri kullanılırsa diğeri kullanılamaz
D. Kalıtım polimorfizmi kolaylaştırabilir ama ön koşulu değildir
E. Polimorfizm için ortak bir üst sınıf zorunludur
TipCevaplar ve gerekçeler
Madde 1. Doğru: B. Döngü, nesnenin hangi sınıftan geldiğini bilmeden send() metodunu çağırır. EmailNotification e-posta metnini, SmsNotification SMS metnini döndürür.
A yanlış: Python listeleri karışık türleri tutabilir.
C yanlış: Döngü iki tur döner ve her turda yazdırır.
D yanlış: Çağrı, listedeki her nesnenin kendi sınıfındaki metoda gider.
E yanlış: Ortak üst sınıf gerekmez; iki nesnede de send metodu vardır.
Madde 2. Doğru: C. Nesnenin hangi sınıftan olduğuna değil, gereken metoda sahip olup olmadığına bakılır. İkisinde de send(message) metodu olduğu için aynı döngüde kullanılabilirler; aralarında kalıtım ilişkisi gerekmez.
A yanlış: Kalıtımdan sonra ortak davranışın hep bir üst sınıftan geldiği sanılabilir. Ama Python kendiliğinden ortak bir üst sınıf oluşturmaz.
B yanlış: Aynı adlı metotlar iki sınıfı birbirine bağlıyormuş gibi görünür. Ama sınıflar birleştirilmez; ayrı kalırlar.
D yanlış: Farklı türler aynı listede sorunsuz çalıştığı için arka planda bir tür denetimi yapıldığı sanılabilir. Döngü hiç tür denetimi yapmaz; yalnız metodu çağırır.
E yanlış: Her sınıfın object sınıfından türediğini bilen öğrenci ortak üst sınıfı burada arayabilir. Bu doğrudur ama object sınıfında send metodu yoktur.
Madde 3. Doğru: A. Ortak metodun ne aldığı, ne döndürdüğü ve hangi hatayı yükselttiği belli olmalıdır. Sözleşmeyi yazan ayrı bir sınıf olmasa da bu bir davranış sözleşmesidir; yoksa çağıran kod neye güveneceğini bilemez.
B yanlış: Python türleri önceden denetlemediği için sözleşme de yok sanılabilir. Ama Python sözleşmeyi zorla uygulatmaz; sözleşmeyi kodu tasarlayan kişi belirler.
C yanlış: Ön kontrol güvenlik sağlıyormuş gibi görünür. Ama hasattr yalnız adın erişilebilir olduğunu söyler; metodun ne aldığını ve ne döndürdüğünü söylemez.
D yanlış: Polimorfizm çoğu zaman kalıtımla anlatıldığı için duck typing’in de onu gerektirdiği sanılabilir. Duck typing kalıtım gerektirmez; ortak üst sınıfı olmayan sınıflarla da çalışır.
E yanlış: ABC beklentiyi açıkça yazdığı için duck typing’in ön koşulu gibi görünebilir. ABC beklentiyi kodda açıkça yazmanıza yarar ama zorunlu değildir.
Madde 4. Doğru: C. Ne yapılacağına nesne değil, fonksiyondaki koşul zinciri karar verir. Bütün sınıflarda ortak bir send(message) metodu olursa fonksiyon return notification.send(message) satırına iner; yeni türler fonksiyonu değiştirmeden eklenir.
A yanlış: Tür denetimi hangi dalın çalışacağını açıkça gösterdiği için güvenli görünür. Ama uzayan tür zinciri yüzünden her yeni tür bu fonksiyonu değiştirmeyi gerektirir.
B yanlış:is işlecinin sayı ve metinlerde yanıltıcı olduğunu bilen öğrenci burada da hata bekleyebilir. Ama her sınıf nesnesi tektir; type(x) is EmailNotification doğru çalışır. Sorun type() değil, onunla uzayan koşul zinciridir.
D yanlış: Son dalı else yapmak bir koşulu sildiği için çözüm gibi görünür. Ama else zinciri kısaltmaz; her yeni tür yine yeni bir dal ister.
E yanlış: Mesajı ayrıca geçirmek fazlalık gibi görünebilir. Ama parametre sayısı sorun değildir; send(message) de mesajı parametre olarak alır.
Madde 5. Doğru: B. Her bildirim sınıfı aynı adlı send(message) metodunu taşıyınca fonksiyon yalnız notification.send(message) çağırır. Ne yapılacağına nesne karar verince yeni bir tür eklemek için çağıran kodu değiştirmek gerekmez.
A yanlış: Her türün kodu ayrı yerde durduğu için düzenli görünür. Ama çağıran kod yine hangi fonksiyonu çağıracağına karar vermek zorunda kalır.
C yanlış:isinstance() alt sınıfları da kabul ettiği için daha doğru bir denetim gibi görünür. Ama zincir yine uzar. Sorun tür denetiminin kendisi değil, ne yapılacağının nesnenin dışında seçilmesidir.
D yanlış: Sınıf sayısı azalınca tür denetimine gerek kalmayacakmış gibi görünür. Ama koşul zinciri bu kez sınıfın içine taşınır.
E yanlış:elif satırları kaybolduğu için zincir çözülmüş gibi görünür. Zincir görünmez olur ama her yeni tür için sözlüğe yine bir satır eklemek gerekir.
Madde 6. Doğru: D. Dışarıdan gelen veriyi doğrulamak (sınır doğrulaması) ve serileştirme böyle durumlardır. Tür kontrolü tek başına hata değildir. Kod kokusu, nesnenin kendi metodunu çağırmak yerine her yeni türde uzayan bir koşul zinciri yazmaktır.
A yanlış: İki fonksiyon da nesneyi sorguladığı için birlikte kullanılıyormuş gibi görünür. isinstance() türü, hasattr() bir adın varlığını sorar; birlikte kullanılmaları gerekmez.
B yanlış: Uzayan tür zinciri kod kokusu diye anlatıldığı için her tür kontrolü yasakmış gibi algılanabilir. Böyle bir yasak yoktur; yerinde kullanımları vardır.
C yanlış:isinstance() alt sınıfları da kabul ettiği için kalıtımla ilgili bir araç sanılabilir. Ama ne zaman kullanılacağı kalıtımın olup olmamasına bağlı değildir.
E yanlış: Erken denetim hatayı yakalamanın güvenli yolu gibi görünür. Ama gereksiz ön kontroller kodu uzatır; duck typing’de nesnenin türü sorulmaz.
Madde 7. Doğru: E.hasattr() yalnız adın varlığını söyler. Adın çağrılabilir olup olmadığı, hangi parametreleri aldığı ve beklenen işi yapıp yapmadığı bilinmez. Bu yüzden duck typing “önce her şeyi hasattr ile kontrol et” biçiminde anlaşılmamalıdır.
A yanlış: Ad bulunduğuna göre çağrının da sorunsuz olacağı sanılabilir. Ama çağrı yanlış argümanla ya da metodun içindeki bir hatayla yine istisna yükseltebilir.
B yanlış: Metot bir sınıfta tanımlandığı için adın varlığı bir tür ilişkisini düşündürür. Ama hasattr() tür ilişkisi hakkında bilgi vermez.
C yanlış: Örneklerdeki send metotları hep metin döndürdüğü için bu beklenti oluşabilir. Ama hasattr() dönüş türü hakkında bilgi vermez.
D yanlış: Adı send olan bir metot gönderme işini yapıyormuş gibi görünür. Ama adın bulunması, metodun sözleşmeye uygun çalışacağını garanti etmez.
Madde 8. Doğru: E. LBYL işi yapmadan önce koşulu kontrol eder; EAFP işi doğrudan dener, beklenen hata çıkarsa onu yakalar. İkisinden biri her zaman doğru değildir. Bir yanda gereksiz ön kontroller, öbür yanda gerçek hataları da yutan geniş bir except vardır; ikisi arasındaki denge gözetilir.
A yanlış: EAFP dosya örnekleriyle sık anlatıldığı için böyle bir ayrım varmış gibi görünür. Böyle bir alan ayrımı yoktur.
B yanlış: İki yaklaşım da hataya karşı önlem aldığı için aynı sanılabilir. Ama biri işten önce kontrol eder, öbürü işi dener ve hatayı sonra yakalar.
C yanlış: EAFP “dene, hata çıkarsa yakala” diye özetlendiği için her hatayı yakalamak da buna uyuyor gibi görünür. Ama yalnız beklenen hata türü yakalanmalıdır; geniş except gerçek hataları da yutar.
D yanlış: Ön kontrol yapıldığı için istisnaya yer kalmadığı sanılabilir. Ama kontrol yapılsa da istisnalar yine oluşabilir.
Madde 9. Doğru: A.except yalnız “nesnede send yok” durumunu değil, metodun içindeki yazım hatalarını da yakalar; gerçek bir programlama hatası “desteklenmiyor” diye yorumlanır. Her nesnede send() bulunacağı belliyse metodu doğrudan çağırmak çoğu zaman en sade çözümdür.
B yanlış: Tek bir hata türü yakalandığı için öteki hataların kaçacağı düşünülebilir. Ama sorun darlık değil, aynı hata türünün iki farklı nedenden gelebilmesidir.
C yanlış: Uyarı EAFP kalıbı üzerinden yapıldığı için yaklaşımın kendisi kötüymüş gibi görünür. Python’da EAFP önerilir; uyarı yalnız istisnanın körlemesine yakalanmasıyla ilgilidir.
D yanlış: Hata mesajı hiçbir yerde görünmediği için sorunun bu olduğu sanılabilir. as error hata mesajına erişmeye yarar ama asıl risk, hatanın yanlış yorumlanmasıdır.
E yanlış: Kısa try bloklarında çoğu zaman yalnız bir çağrı görüldüğü için atamanın yasak olduğu sanılabilir. Yapılabilir; söz dizimi geçerlidir.
Madde 10. Doğru: D. Kalıtım sınıflar arasındaki bir ilişkidir; polimorfizm farklı nesnelerin aynı metot çağrısıyla kullanılabilmesidir. İki kavram sık birlikte anılır ama aynı şey değildir. Bölümdeki bildirim örneğinde polimorfizm kalıtım olmadan, duck typing ile elde edildi.
A yanlış: Override örnekleri polimorfizmi kalıtımla birlikte gösterdiği için ikisi aynı sanılabilir. Ama kalıtımsız polimorfizm örnekleri bunu çürütür.
B yanlış: Bu bölümde kalıtım polimorfizmle birlikte anıldığı için tek amacı buymuş gibi görünebilir. Ama kalıtım, üst sınıftaki kodu alt sınıfta yeniden kullanmak ve türler arasında ilişki kurmak için de kullanılır.
C yanlış: Duck typing kalıtımsız çalıştığı için ikisi arasında seçim yapmak gerekiyormuş gibi görünür. Ama birlikte kullanılabilirler: bir alt sınıf, override ettiği metotla polimorfik çağrıya katılabilir.
E yanlış: Polimorfizm çoğu kaynakta ortak üst sınıfla anlatıldığı için bu bir şart sanılabilir. Python’da zorunlu değildir; send metodu olan her nesne aynı döngüde kullanılabilir.
Tek sayfa özet
Polimorfizmde aynı metot çağrısı her nesnede o nesnenin kendi işini yapar.
Duck typing nesnenin sınıfına değil metotlarına bakar; bu yüzden ortak bir üst sınıf her zaman gerekmez.
hasattr() yalnız bir adın bulunup bulunmadığını söyler; metodun sözleşmeye uygun çalışacağını garanti etmez.
LBYL işten önce koşulu kontrol eder, EAFP işi dener ve hatayı yakalar. EAFP’de yalnız beklediğiniz hata türünü yakalayın.
Nesnenin türünü sorgulamak yerine metodunu çağırırsanız yeni bir tür eklemek için çağıran kodu değiştirmeniz gerekmez.
Kalıtım sınıflar arasındaki bir ilişkidir; polimorfizm nesneleri kullanma biçimidir ve kalıtım olmadan da mümkündür.
Bu bölümün kazanımları
Bu bölümü bitiren öğrenci:
Aynı metot çağrısının farklı nesnelerde farklı iş yaptığını örnekle gösterir.
Ortak üst sınıf olmadan da polimorfizmin mümkün olduğunu açıklar.
Her yeni türde uzayan tür koşulu zincirini kod kokusu olarak tanır ve yerine ortak bir metot çağrısı koyar.
isinstance() kullanımının hangi durumda yerinde olduğunu belirler.