Duck typing, Python'un temel prensiplerinden biridir; bir nesne, sınıf hiyerarşisine bağlı olarak değil, davranışına göre değerlendirilir.
Terim, "Eğer bir şey bir ördeğe benziyorsa, ördek gibi yüzüyorsa ve ördek gibi gagalıyorsa - o zaman o bir ördektir" atasözünden gelmektedir. Python'da bir nesnenin davranışı (arayüzü), ona ait olduğu sınıftan daha önemlidir. Bu, "duck typing" ilkesini - davranışa göre tip belirleme (yapısal tip belirleme) - uygular.
Duck typing'in maksimum esneklik sağlıyormuş gibi görünmesi. Ancak bu, gizli hataların sayısını artırır: Program, nesne gerekli arayüzü desteklemiyorsa, yalnızca çalışma zamanında "bozulur".
Tip kontrolü yapmak yerine (isinstance veya type aracılığıyla) nesne üzerinde gerekli metodları çağırmayı deneyen fonksiyonlar yazın; eğer destekliyorsa, her şey çalışacaktır. En kötü durumda - beklenmedik nesneleri işlemek için AttributeError veya TypeError'ı yakalayın.
Örnek:
def quack_and_walk(duck): duck.quack() duck.walk() class Robot: def quack(self): print("Quaklayabilirim!") def walk(self): print("Yürüyüyorum") quack_and_walk(Robot()) # her şey çalışacak!
Anahtar özellikler:
Python'da isinstance ile türü kontrol edebilir miyiz ve bu duck typing için doğru mu?
Hayır. Duck typing, tam olarak katı tür kontrolüne karşıdır. Nesnenin kökeninden ziyade davranışla çalışmak daha doğrudur.
Duck typing'i soyut temel sınıflar (ABC) ile gerçekleştirebilir miyiz?
Kısmen. Soyut sınıflar, statik yapı öğeleri getirir. Duck typing, akrabalığı açıklamayı gerektirmez - sadece gerekli metodları uygulamanız gerekir. Ancak Python 3.8 ile typing.Protocol modülü, bizi yapısal tiplemeye yaklaştırır.
Duck typing, sihirli metodlarla (len, getitem vb.) çalışabilir mi?
Evet. Eğer bir nesne gerekli metodu (len) gerçekleştiriyorsa, onu fonksiyonlarda, örneğin, len(obj) gibi kullanmak mümkündür ve bu duck typing'e göre çalışır.
Bir geliştirici, kontrol etmeden run() metoduna sahip her şeyi kabul eden bir fonksiyon yazar. Koda bu metodu olmayan bir nesne eklenir — ve hata yalnızca çalışma zamanında ortaya çıkar.
Artılar:
Eksiler:
Duck typing kullanımı, ancak try/except ve arayüz belgeleri ile:
def run_task(obj): try: obj.run() except AttributeError: print("Nesne görevi başlatmayı desteklemiyor!")
Artılar:
Eksiler: