August 14, 2023

Introduction to Operator Overloading | Python Advanced

Yazılım'da pek çok operatörü bir ara kullanmaktayız. Bu operatörler çoğu zaman tek bir anlama geliyorlar. Örneğin: İki string'in toplamı ikisinin birleşimi iken iki listenin toplamı o iki listenin extend edilmesidir. E iyi de, artı sembolü integral türleri toplamak için değil mi? Evet ama bu saydığım örneklerde de olduğu gibi standart kütüphanemizdeki türlerin de kendi operator overloading implementasyonları var.

Mesela şu ifadenin çıktısı normalde ne beklenirdi?

class Path:
    def __init__(self, path: str):
        self.path = self.path.rstrip("/")
print(Path("/usr") / "bin")
.# unsupported operand type(s) for /: 'Path' and 'str'
.# peki ya, zaten bir operator overloading implementasyonu yapsaydık
class Path:
    def __init__(self, path: str):
        self.path = path.rstrip("/")
    def __truediv__(self, other):
        if isinstance(other, Path):
            other.path = other.path.lstrip("/")
            return '/'.join((self.path, other.path))
        else:
            return '/'.join((self.path, str(other)))
            
print(Path("/usr") / "bin")
.# çıktı: /usr/bin
.# peki ya, ben öncelik sırasını değiştirirsem;
.# hata aldık: unsupported operand type(s) for /: 'Path' and 'str'
.# neyseki çözmek o kadar da zor değil
.# sağ taraf ifadeleri için fonksiyona 'r' öneki koymak
class Path:
    def __init__(self, path: str):
        self.path = path.lstrip("/")
    def __rtruediv__(self, other):
        if isinstance(other, Path):
            other.path = other.path.rstrip("/")
            return '/'.join((self.path, other.path))
        else:
            return '/'.join((self.path, str(other)))
            
print("bin" / Path("/usr"))
.# çıktı: bin/usr
Not: Bu doküman python'da operator overloading'in işleneceği Python yayınıma aittir.