Python Operatörü Aşırı Yüklemesi

Python'da bir işlecin anlamını kullanılan işlenenlere bağlı olarak değiştirebilirsiniz. Bu eğitimde, Python Nesne Yönelimli Programlamada operatör aşırı yüklemesinin nasıl kullanılacağını öğreneceksiniz.

Python Operatörü Aşırı Yüklemesi

Python operatörleri yerleşik sınıflar için çalışır. Ancak aynı operatör farklı türlerde farklı davranır. Örneğin, +operatör iki sayı üzerinde aritmetik toplama yapacak, iki listeyi birleştirecek veya iki dizeyi birleştirecektir.

Python'da aynı operatörün bağlama göre farklı anlamlara sahip olmasını sağlayan bu özelliğe operatör aşırı yükleme denir.

Peki onları kullanıcı tanımlı bir sınıfın nesneleriyle kullandığımızda ne olur? 2 boyutlu koordinat sisteminde bir noktayı simüle etmeye çalışan aşağıdaki sınıfı ele alalım.

 class Point: def __init__(self, x=0, y=0): self.x = x self.y = y p1 = Point(1, 2) p2 = Point(2, 3) print(p1+p2)

Çıktı

 Geri izleme (en son çağrı): Dosya "", satır 9, baskıda (p1 + p2) TypeError: +: 'Nokta' ve 'Nokta' için desteklenmeyen işlenen türleri

Burada, TypeErrorPython iki Pointnesneyi nasıl toplayacağını bilmediği için a'nın yükseltildiğini görebiliriz .

Ancak bu görevi Python'da operatör aşırı yüklemesi yoluyla gerçekleştirebiliriz. Ama önce özel fonksiyonlar hakkında bir fikir edelim.

Python Özel İşlevleri

Çift alt çizgi ile başlayan sınıf işlevlerine __Python'da özel işlevler denir.

Bu işlevler, bir sınıf için tanımladığımız tipik işlevler değildir. __init__()Yukarıda tanımlanan fonksiyonu bunlardan biridir. Bu sınıftan her yeni nesne oluşturduğumuzda çağrılır.

Python'da çok sayıda başka özel işlev vardır. Onlar hakkında daha fazla bilgi edinmek için Python Özel İşlevleri'ni ziyaret edin.

Özel fonksiyonları kullanarak sınıfımızı yerleşik fonksiyonlarla uyumlu hale getirebiliriz.

 >>> p1 = Point(2,3) >>> print(p1) 

print()İşlevin, Pointsahip olduğumuz şey yerine nesnenin koordinatlarını yazdırmasını istediğimizi varsayalım . __str__()Sınıfımızda nesnenin nasıl yazdırılacağını kontrol eden bir yöntem tanımlayabiliriz . Bunu nasıl başarabileceğimize bakalım:

 class Point: def __init__(self, x = 0, y = 0): self.x = x self.y = y def __str__(self): return "((0),(1))".format(self.x,self.y)

Şimdi print()işlevi tekrar deneyelim .

 class Point: def __init__(self, x=0, y=0): self.x = x self.y = y def __str__(self): return "((0), (1))".format(self.x, self.y) p1 = Point(2, 3) print(p1)

Çıktı

 (2, 3)

Bu daha iyi. Yerleşik işlevi kullandığımızda str()ya da format().

 >>> str(p1) '(2,3)' >>> format(p1) '(2,3)'

Yani, str(p1)veya kullandığınızda format(p1), Python dahili olarak p1.__str__()yöntemi çağırır . Bu nedenle adı, özel işlevler.

Şimdi operatör aşırı yüklemesine geri dönelim.

+ Operatörünü aşırı yükleme

+Operatörü aşırı yüklemek __add__()için sınıfta fonksiyon uygulamamız gerekecek . Büyük güç büyük sorumluluk getirir. Bu işlevin içinde istediğimizi yapabiliriz. Ancak Pointkoordinat toplamının bir nesnesini döndürmek daha mantıklıdır .

 class Point: def __init__(self, x=0, y=0): self.x = x self.y = y def __str__(self): return "((0),(1))".format(self.x, self.y) def __add__(self, other): x = self.x + other.x y = self.y + other.y return Point(x, y)

Şimdi toplama işlemini tekrar deneyelim:

 class Point: def __init__(self, x=0, y=0): self.x = x self.y = y def __str__(self): return "((0),(1))".format(self.x, self.y) def __add__(self, other): x = self.x + other.x y = self.y + other.y return Point(x, y) p1 = Point(1, 2) p2 = Point(2, 3) print(p1+p2)

Çıktı

 (3,5)

Aslında olan şey, kullandığınızda p1 + p2, p1.__add__(p2)sırayla Python çağrılarıdır Point.__add__(p1,p2). Bundan sonra da belirlediğimiz şekilde toplama işlemi gerçekleştirilir.

Benzer şekilde, diğer operatörleri de aşırı yükleyebiliriz. Gerçekleştirmemiz gereken özel işlev aşağıda tablo halinde verilmiştir.

Şebeke İfade Dahili olarak
İlave p1 + p2 p1.__add__(p2)
Çıkarma p1 - p2 p1.__sub__(p2)
Çarpma işlemi p1 * p2 p1.__mul__(p2)
Güç p1 ** p2 p1.__pow__(p2)
Bölünme p1 / p2 p1.__truediv__(p2)
Kat Bölümü p1 // p2 p1.__floordiv__(p2)
Kalan (modulo) p1 % p2 p1.__mod__(p2)
Bit Düzeyinde Sola Kaydırma p1 << p2 p1.__lshift__(p2)
Bit Düzeyinde Sağa Kaydırma p1>> p2 p1.__rshift__(p2)
Bitsel AND p1 & p2 p1.__and__(p2)
Bit tabanlı VEYA p1 | p2 p1.__or__(p2)
Bitsel ÖZELVEYA p1 p2 p1.__xor__(p2)
Bitsel DEĞİL ~p1 p1.__invert__()

Karşılaştırma Operatörlerini Aşırı Yükleme

Python, operatör aşırı yüklemesini yalnızca aritmetik operatörlerle sınırlamaz. Karşılaştırma operatörlerini de aşırı yükleyebiliriz.

Biz az sembol uygulamak istediğini varsayalım <bizim de sembolü Pointsınıfında.

Bu noktaların büyüklüğünü kökene göre karşılaştıralım ve sonucu bu amaçla döndürelim. Aşağıdaki gibi uygulanabilir.

 # overloading the less than operator class Point: def __init__(self, x=0, y=0): self.x = x self.y = y def __str__(self): return "((0),(1))".format(self.x, self.y) def __lt__(self, other): self_mag = (self.x ** 2) + (self.y ** 2) other_mag = (other.x ** 2) + (other.y ** 2) return self_mag < other_mag p1 = Point(1,1) p2 = Point(-2,-3) p3 = Point(1,-1) # use less than print(p1 

Output

 True False False

Similarly, the special functions that we need to implement, to overload other comparison operators are tabulated below.

Operator Expression Internally
Less than p1 < p2 p1.__lt__(p2)
Less than or equal to p1 <= p2 p1.__le__(p2)
Equal to p1 == p2 p1.__eq__(p2)
Not equal to p1 != p2 p1.__ne__(p2)
Greater than p1> p2 p1.__gt__(p2)
Greater than or equal to p1>= p2 p1.__ge__(p2)

Ilginç makaleler...