ProgramlamaBackend Geliştirici

Python'da büyülü yöntemler (dunder yöntemleri) nedir, nasıl kullanılır ve bunları kendi sınıflarınızda neden geçersiz kılmalısınız? Uygulama örnekleri verin ve uygulamalarında dikkate almanız gereken nüansları açıklayın.

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

Cevap.

Büyülü yöntemler (veya dunder yöntemleri – double underscore'dan) iki alt çizgi ile başlayan ve biten özel yöntemlerdir, örneğin __init__, __str__, __add__. Bunlar, kendi sınıf örneklerinizi Python'un sözdizimine ve davranışına entegre etmenizi sağlar: aritmetik işlemler, karşılaştırmalar, dizeye dönüştürme, koleksiyon protokolleri ile çalışma vb. üzerine tepkileri tanımlamak için kullanılır.

Örnek:

class Vector: def __init__(self, x, y): self.x = x self.y = y def __add__(self, other): return Vector(self.x + other.x, self.y + other.y) def __str__(self): return f"Vector({self.x}, {self.y})" v1 = Vector(1, 2) v2 = Vector(3, 4) print(v1 + v2) # v1.__add__(v2) çağrılacak, Vector(4, 6) döndürecek

Kandırmaca soru.

Kendi sınıfınızda __eq__ yöntemini uygulamazsanız, nesneleri == operatörü ile nasıl karşılaştırılır?

Cevap: Varsayılan olarak == operatörü, nesneleri kimliklerine (bellek adresine, is operatörüne benzer şekilde) göre karşılaştırır, eğer büyülü __eq__ yöntemi geçersiz kılınmamışsa.

class A: pass print(A() == A()) # False, nesneler "aynı gibi görünüyor".

Konudaki nüansların bilinmediği için gerçek hata örnekleri.


Hikaye

Bir graf yapılarını karşılaştırmak gerektiği bir projede __eq__ yöntemi uygulanmamıştı. Bu nedenle "bir düğüm zaten eklenmiş mi?" kontrolünde yanlış sonuç alınıyordu, çünkü == operatörü nesneleri id'ye göre karşılaştırıyordu, içeriğe göre değil.


Hikaye

REST API yazarken, str(obj) aracılığıyla bir nesneyi log için dizeye dönüştürdüler ama __str__'yi tanımlamayı unuttular. Sonuç olarak, okunamaz bir metin olan <MyObj object at 0x...> gösteriliyordu, bu da sorunların teşhis edilmesini zorlaştırıyordu.


Hikaye

Matematiksel hesaplamalar için bir kütüphanede yalnızca __add__ uygulandı, ancak += operatörü için __iadd__ unutuldu. Bunun sonucunda v += w ifadesi beklenildiği gibi çalışmadı (yeni bir nesne oluşturuldu, eski güncellenmedi) ve bu, karmaşık hesaplamalarda bellek sızıntılarına yol açtı.