ProgramlamaPython Geliştirici

Python'da __call__ metodunun çalışma prensiplerini açıklayın, nerelerde kullanıldığını ve __call__'ı gerçekleştiren bir nesnenin, sıradan bir işlevden ne farkı olduğunu belirtin.

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

Soru Tarihi:

Python'da her şey bir nesnedir ve her işlev de bir nesnedir. Bir sınıf örneğinin işlev gibi çalışmasını sağlayan bir mekanizma gerçekleştirilmiştir. Bunun için, nesneleri çağrılabilir hale getiren özel bir sihirli metod olan call tanıtılmıştır.

Sorun:

Bazen, çağrılabilen bir nesneyi geçmek gerekebilir; örneğin, durumlu fonksiyonlar, kapanışlar, olay işleyici nesneleri vb. Geliştirme mimarisi, bu tür işlevselliğin nasıl doğru bir şekilde uygulanacağını anlamayı gerektirir.

Çözüm:

Bir sınıfta call metodunu uygulayarak, onun örneğini "işlev gibi" çağrılabilir hale getirebiliriz. Bu, sınıfların (durum kapsülleme, miras alma, metodlar) ve işlevlerin (çağrılabilirlik) olanaklarını birleştirmeyi sağlar. Bu yaklaşım, komut nesneleri, karmaşık işleyiciler, sarıcılar vb. oluşturmak için kullanılır.

Kod Örneği:

class Adder: def __init__(self, x): self.x = x def __call__(self, y): return self.x + y add5 = Adder(5) print(add5(10)) # 15'i yazdırır

Ana özellikler:

  • call'ı olan nesneler, iç durumu korur (sıradan bir işlevin aksine).
  • İşlev gibi çağrılabilir, ancak sınıfın metodları ve özellikleri olabilir.
  • Daha ifadeli tasarım desenleri oluşturmaya olanak tanır (örneğin, stratejiler, komutlar).

Zorlayıcı Sorular.

call metodu, sıradan bir işlevin niteliklerini miras alır mı — örneğin, name ve doc?

Hayır, call metoduna sahip bir nesnenin name niteliği olmayacaktır (veya sınıftan devralır). İşlevlerin meta verileri saklanmaz.

call gerçekleştirilmiş bir nesne gerçek bir işlev midir?

Hayır, bu bir sınıf örneğidir, işlev değildir. Sadece "çağrılabilir" davranışını gerçekleştirir. Örneğin, isinstance(obj, types.FunctionType) ile işlevle karşılaştırmak False verir.

call olan bir nesneye, işlev için tasarlanmış bir dekoratör uygulanabilir mi?

Genellikle bu tür dekoratörler, tam olarak bir işlev bekler, nesne değil (örneğin, functools.lru_cache). Kullanım hatalara yol açabilir veya hiç çalışmayabilir.

Tipik Hatalar ve Anti-Paternler

Artılar:

  • Tasarım desenlerinde esneklik.
  • Veri ve davranışı birleştirme olanağı. Eksiler:
  • Kod, yeni başlayan Python geliştiricileri için daha az şeffaf hale gelir.
  • İşlevlerin standart niteliklerinin kaybı; bazı araçların/dekoratörlerin kullanılamaması ihtimali.

Hayattan Bir Örnek

Olumsuz durum: Bir projede ayarları (seviye, dosya adı) saklamak için call ile bir günlüğü sınıf olarak gerçekleştirdiler. Ancak, sinyal işleyicilerinin tam olarak bir işlev beklediğini unuttular ve işleyiciyi kaydederken hatalar aldılar (object is not a function).

Artılar: günlüğün esnek ayarları. Eksiler: beklenen arayüzlerle uyumsuzluk.

Olumlu durum: Başka bir projede, parametreleri saklamak için call ile karmaşık dekoratör işlevleri oluşturmak için bir sınıf kullandılar, bu da test etmeyi kolaylaştırdı.

Artılar: genişletilebilirlik, kullanım kolaylığı. Eksiler: işlev veya lambda ile karşılaştırıldığında daha fazla kod.