Menu
Coddy logo textTech

Operatör Aşırı Yükleme

Coddy'nin Python Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 34 / 64.

Operatör aşırı yükleme (operator overloading), özel sihirli metotları (magic methods) uygulayarak sınıflarınızın Python'un yerleşik operatörleri (+, -, *, vb.) ile çalışmasına olanak tanır.

İşte operatör aşırı yüklemesi (operator overloading) içeren bir sınıf örneği:

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 __mul__(self, scalar):
        return Vector(self.x * scalar, self.y * scalar)
    
    def __str__(self):
        return f"Vector({self.x}, {self.y})"

__add__ metodu, + operatörünü kullandığınızda ne olacağını tanımlar:

v1 = Vector(2, 3)
v2 = Vector(5, 7)
result = v1 + v2  # v1.__add__(v2) çağrısını yapar
print(result)

__mul__ metodu, * operatörünü kullandığınızda ne olacağını tanımlar:

v1 = Vector(2, 3)
scaled = v1 * 3   # v1.__mul__(3) metodunu çağırır
print(scaled)

Çıktı:

Vector(7, 10)
Vector(6, 9)

Karşılaştırma operatörlerini ekleyin:

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 __eq__(self, other):
        return self.x == other.x and self.y == other.y
    
    def __str__(self):
        return f"Vector({self.x}, {self.y})"

v1 = Vector(2, 3)
v2 = Vector(2, 3)
v3 = Vector(1, 1)

print(v1 == v2)  # True - v1.__eq__(v2) çağrılır
print(v1 == v3)  # False

Önemli Nokta: Operatör aşırı yüklemesi (operator overloading), operatörlerin nesnelerinizle nasıl çalışacağını tanımlamak için __add__ (+), __sub__ (-), __mul__ (*), __eq__ (==) gibi sihirli metotları kullanır. Bu, sınıflarınızın Python'un yerleşik operatörleriyle doğal bir şekilde davranmasını sağlar.

challenge icon

Görev

Orta

Bu meydan okumada, parasal tutarları temsil eden ve güçlü operatör aşırı yüklemesine (operator overloading) sahip bir Money sınıfı uygulayacaksınız. Uygulamanız, kapsamlı bir test paketi ile titizlikle test edilecektir.

  • money.py - Bu, düzenlemeniz gereken tek dosyadır. Uygulamanıza rehberlik edecek TODO yorumlarını içeren sınıf tanımını barındırır.
  • driver.py - Uygulamanızı doğrulayan kapsamlı test senaryolarını içerir (değiştirmeyin).

Money sınıfını aşağıdaki özelliklerle uygulayın:

  1. amount (float) ve currency (string) alan bir yapıcı (constructor)
  2. Aynı para birimine sahip Money nesnelerinin toplanması (+)
  3. Tutarı ölçeklendirmek için bir sayı ile çarpma (*)
  4. Money nesneleri arasında eşitlik karşılaştırması (==)
  5. “X.XX CUR” formatında dize (string) temsili

Kopya kağıdı

Operatör aşırı yükleme (operator overloading), sınıfların özel sihirli metotları (magic methods) uygulayarak Python'ın yerleşik operatörleriyle çalışmasına olanak tanır:

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 __mul__(self, scalar):
        return Vector(self.x * scalar, self.y * scalar)
    
    def __eq__(self, other):
        return self.x == other.x and self.y == other.y
    
    def __str__(self):
        return f"Vector({self.x}, {self.y})"

Operatör aşırı yükleme için yaygın sihirli metotlar:

  • + operatörü için __add__
  • - operatörü için __sub__
  • * operatörü için __mul__
  • == operatörü için __eq__
  • dize temsili için __str__

Kullanım örneği:

v1 = Vector(2, 3)
v2 = Vector(5, 7)
result = v1 + v2  # v1.__add__(v2) metodunu çağırır
scaled = v1 * 3   # v1.__mul__(3) metodunu çağırır
print(v1 == v2)   # v1.__eq__(v2) metodunu çağırır

Kendin dene

from money import Money

# Test senaryosu işleyicisi
test_case = input()

def test_basic_functionality():
    # Başlatma ve dize gösterimini test et
    m1 = Money(10.0, "USD")
    assert str(m1) == "10.00 USD", f"__str__ method failed, got {str(m1)}"
    
    # Toplamayı test et
    m2 = Money(20.0, "USD")
    m3 = m1 + m2
    assert str(m3) == "30.00 USD", f"Addition failed, got {str(m3)}"
    
    # Farklı para birimi eklemeyi test et
    m4 = Money(20.0, "EUR")
    try:
        m5 = m1 + m4
        assert False, "Adding different currencies should raise an error"
    except ValueError as e:
        assert str(e) == "Cannot add different currencies", f"Wrong error message: {str(e)}"
    
    # Çarpmayı test et
    m6 = m1 * 3
    assert str(m6) == "30.00 USD", f"Multiplication failed, got {str(m6)}"
    
    # Eşitliği test et
    assert m1 == Money(10.0, "USD"), "Equality test failed"
    assert m1 != m2, "Inequality test failed"
    
    print("All basic functionality tests passed!")

def test_zero_values():
    # Sıfır tutarı ile test et
    m1 = Money(0.0, "USD")
    assert str(m1) == "0.00 USD", f"Zero amount string representation failed, got {str(m1)}"
    
    # Sıfır ile toplamayı test et
    m2 = Money(10.0, "USD")
    m3 = m1 + m2
    assert str(m3) == "10.00 USD", f"Addition with zero failed, got {str(m3)}"
    
    # Sıfır ile çarpmayı test et
    m4 = m2 * 0
    assert str(m4) == "0.00 USD", f"Multiplication by zero failed, got {str(m4)}"
    
    # Sıfır tutarı ile eşitliği test et
    assert m1 == Money(0.0, "USD"), "Equality with zero amount failed"
    assert m1 != m2, "Inequality with zero amount failed"
    
    print("All zero value tests passed!")

def test_negative_values():
    # Negatif tutar ile test et
    m1 = Money(-10.0, "USD")
    assert str(m1) == "-10.00 USD", f"Negative amount string representation failed, got {str(m1)}"
    
    # Negatif tutarlarla toplamayı test et
    m2 = Money(20.0, "USD")
    m3 = m1 + m2
    assert str(m3) == "10.00 USD", f"Addition with negative amount failed, got {str(m3)}"
    
    m4 = Money(-5.0, "USD")
    m5 = m1 + m4
    assert str(m5) == "-15.00 USD", f"Addition of two negative amounts failed, got {str(m5)}"
    
    # Negatif skaler ile çarpmayı test et
    m6 = m2 * -2
    assert str(m6) == "-40.00 USD", f"Multiplication by negative scalar failed, got {str(m6)}"
    
    # Negatif tutarlarla eşitliği test et
    assert m1 == Money(-10.0, "USD"), "Equality with negative amount failed"
    assert m1 != m2, "Inequality with negative amount failed"
    
    print("All negative value tests passed!")

def test_large_values():
    # Çok büyük tutarlarla test et
    m1 = Money(1000000.0, "USD")
    assert str(m1) == "1000000.00 USD", f"Large amount string representation failed, got {str(m1)}"
    
    # Büyük tutarlarla toplamayı test et
    m2 = Money(2000000.0, "USD")
    m3 = m1 + m2
    assert str(m3) == "3000000.00 USD", f"Addition with large amounts failed, got {str(m3)}"
    
    # Büyük skaler ile çarpmayı test et
    m4 = m1 * 1000
    assert str(m4) == "1000000000.00 USD", f"Multiplication with large scalar failed, got {str(m4)}"
    
    print("All large value tests passed!")

def test_precision():
    # Ondalıklı tutarlarla test et
    m1 = Money(10.25, "USD")
    assert str(m1) == "10.25 USD", f"Fractional amount string representation failed, got {str(m1)}"
    
    m2 = Money(10.2, "USD")
    assert str(m2) == "10.20 USD", f"Two decimal place formatting failed, got {str(m2)}"
    
    # Ondalıklı tutarlarla toplamayı test et
    m3 = Money(0.75, "USD")
    m4 = m1 + m3
    assert str(m4) == "11.00 USD", f"Addition with fractional amounts failed, got {str(m4)}"
    
    # Ondalıklı skaler ile çarpmayı test et
    m5 = m1 * 0.5
    assert str(m5) == "5.13 USD", f"Multiplication with fractional scalar failed, got {str(m5)}"
    
    print("All precision tests passed!")

def test_type_validation():
    try:
        # Bu işlemler hatasız çalışmalıdır
        m1 = Money(10.0, "USD")
        m2 = m1 * 2
        m3 = m1 * 2.5
        
        # Farklı türlerle eşitliği test et
        assert (m1 == "10.00 USD") == False, "Equality with string should return False"
        assert (m1 == 10.0) == False, "Equality with number should return False"
        
        print("All type validation tests passed!")
    except Exception as e:
        print(f"Type validation test failed: {e}")

def test_currency_case_sensitivity():
    # Para birimi büyük/küçük harf duyarlılığını test et
    m1 = Money(10.0, "USD")
    m2 = Money(10.0, "usd")
    
    # Para birimleri büyük/küçük harfe duyarlı olmalıdır
    assert m1 != m2, "Currency comparison should be case-sensitive"
    
    # Farklı harf durumlarını eklemek başarısız olmalıdır
    try:
        m3 = m1 + m2
        assert False, "Adding different currency cases should raise an error"
    except ValueError as e:
        assert str(e) == "Cannot add different currencies", f"Wrong error message: {str(e)}"
    
    print("All currency case sensitivity tests passed!")

def test_performance():
    # Birçok Money nesnesi oluştur ve işlemler gerçekleştir
    base = Money(1.0, "USD")
    result = base
    
    # 1000 toplama işlemi gerçekleştir
    for i in range(1000):
        result = result + Money(1.0, "USD")
    
    assert str(result) == "1001.00 USD", f"Performance test addition failed, got {str(result)}"
    
    # 10 çarpma işlemi gerçekleştir
    result = base
    for i in range(10):
        result = result * 2
    
    assert str(result) == "1024.00 USD", f"Performance test multiplication failed, got {str(result)}"
    
    print("All performance tests passed!")

# Girdiye göre uygun testi çalıştır
if test_case == "basic_test":
    test_basic_functionality()
elif test_case == "zero_values":
    test_zero_values()
elif test_case == "negative_values":
    test_negative_values()
elif test_case == "large_values":
    test_large_values()
elif test_case == "precision":
    test_precision()
elif test_case == "type_validation":
    test_type_validation()
elif test_case == "currency_case":
    test_currency_case_sensitivity()
elif test_case == "performance":
    test_performance()
else:
    print(f"Unknown test case: {test_case}")
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Object Oriented Programming bölümündeki tüm dersler