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
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".
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ı.