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.
Görev
OrtaBu 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:
amount(float) vecurrency(string) alan bir yapıcı (constructor)- Aynı para birimine sahip Money nesnelerinin toplanması (
+) - Tutarı ölçeklendirmek için bir sayı ile çarpma (
*) - Money nesneleri arasında eşitlik karşılaştırması (
==) - “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ırKendin 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}")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
1OOP Temelleri
Harici DosyalarOOP'ye GirişSınıflar ve Nesnelerself ParametresiMetotlarÖzniteliklerYapıcı Metot (__init__)Özet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtımsuper() FonksiyonuMetot Geçersiz KılmaÇoklu KalıtımMetot Çözümleme SırasıÖzet - Çalışan Hiyerarşisi7Özel Metotlar
Sihirli Metotlara GirişOperatör Aşırı YüklemeKapsayıcı Sihirli MetotlarıÖzet - Özel Liste10Tasarım Kalıpları Bölüm 1
Tasarım kalıplarına girişSingleton KalıbıFactory KalıbıObserver KalıbıStrategy Kalıbı13Final Meydan Okumaları
E-öğrenme PlatformuBankacılık SistemiOyun Karakteri GeliştirmeAraç Kiralama Servisi5Çok Biçimlilik (Polymorphism)
Metot Geçersiz Kılmaya Yeniden BakışDuck TypingSoyut Sınıflar ve MetotlarArayüz TasarımıÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kompozisyon ve KalıtımMixinsStatik ve Sınıf MetotlarıSınıf DekoratörleriBağlam Yöneticileri11Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit Kalıbı