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, TypeError
Python iki Point
nesneyi 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, Point
sahip 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 Point
koordinat 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ü Point
sı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)