העמסת אופרטורים
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Python של Coddy. שיעור 34 מתוך 64.
העמסת אופרטורים מאפשרת למחלקות שלך לעבוד עם האופרטורים המובנים של Python (+, -, *, וכו׳) באמצעות מימוש מתודות קסם מיוחדות.
הנה דוגמה למחלקה עם העמסת אופרטורים:
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__ מגדירה מה קורה כשמשתמשים באופרטור +:
v1 = Vector(2, 3)
v2 = Vector(5, 7)
result = v1 + v2 # קורא ל־v1.__add__(v2)
print(result)המתודה __mul__ מגדירה מה קורה כשמשתמשים באופרטור *:
v1 = Vector(2, 3)
scaled = v1 * 3 # קורא ל־v1.__mul__(3)
print(scaled)פלט:
Vector(7, 10)
Vector(6, 9)הוסיפו אופרטורי השוואה:
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)
print(v1 == v3) # Falseנקודה מרכזית: העמסת אופרטורים משתמשת בשיטות קסם כמו __add__ (+), __sub__ (-), __mul__ (*), __eq__ (==) כדי להגדיר כיצד אופרטורים פועלים עם האובייקטים שלך. כך המחלקות שלך מתנהגות באופן טבעי עם האופרטורים המובנים של Python.
אתגר
בינוניבאתגר הזה תממשו מחלקת Money שמייצגת סכומים כספיים באמצעות העמסת אופרטורים מקיפה. המימוש שלכם ייבדק ביסודיות מול חבילת בדיקות מקיפה.
money.py- זהו הקובץ היחיד שעליכם לערוך. הוא מכיל את הגדרת המחלקה עם הערות TODO שמנחות אתכם במימוש.driver.py- מכיל תרחישי בדיקה רבים שמוודאים את תקינות המימוש שלכם (אל תשנו אותו).
ממשו את המחלקה Money עם התכונות הבאות:
- בנאי שמקבל
amount(מספר עשרוני) ו-currency(מחרוזת) - חיבור (
+) של אובייקטים מסוג Money בעלי אותו מטבע - כפל (
*) במספר כדי לשנות את קנה המידה של הסכום - השוואת שוויון (
==) בין אובייקטים מסוג Money - ייצוג כמחרוזת בתבנית “X.XX CUR”
נסו בעצמכם
from money import Money
# מטפל במקרי בדיקה
test_case = input()
def test_basic_functionality():
# בדיקת אתחול וייצוג כמחרוזת
m1 = Money(10.0, "USD")
assert str(m1) == "10.00 USD", f"__str__ method failed, got {str(m1)}"
# בדיקת חיבור
m2 = Money(20.0, "USD")
m3 = m1 + m2
assert str(m3) == "30.00 USD", f"Addition failed, got {str(m3)}"
# בדיקת חיבור של מטבעות שונים
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)}"
# בדיקת כפל
m6 = m1 * 3
assert str(m6) == "30.00 USD", f"Multiplication failed, got {str(m6)}"
# בדיקת שוויון
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():
# בדיקה עם סכום אפס
m1 = Money(0.0, "USD")
assert str(m1) == "0.00 USD", f"Zero amount string representation failed, got {str(m1)}"
# בדיקת חיבור עם אפס
m2 = Money(10.0, "USD")
m3 = m1 + m2
assert str(m3) == "10.00 USD", f"Addition with zero failed, got {str(m3)}"
# בדיקת כפל באפס
m4 = m2 * 0
assert str(m4) == "0.00 USD", f"Multiplication by zero failed, got {str(m4)}"
# בדיקת שוויון עם סכום אפס
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():
# בדיקה עם סכום שלילי
m1 = Money(-10.0, "USD")
assert str(m1) == "-10.00 USD", f"Negative amount string representation failed, got {str(m1)}"
# בדיקת חיבור עם סכומים שליליים
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)}"
# בדיקת כפל בסקלר שלילי
m6 = m2 * -2
assert str(m6) == "-40.00 USD", f"Multiplication by negative scalar failed, got {str(m6)}"
# בדיקת שוויון עם סכומים שליליים
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():
# בדיקה עם סכומים גדולים מאוד
m1 = Money(1000000.0, "USD")
assert str(m1) == "1000000.00 USD", f"Large amount string representation failed, got {str(m1)}"
# בדיקת חיבור של סכומים גדולים
m2 = Money(2000000.0, "USD")
m3 = m1 + m2
assert str(m3) == "3000000.00 USD", f"Addition with large amounts failed, got {str(m3)}"
# בדיקת כפל בסקלר גדול
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():
# בדיקה עם סכומים שבריים
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)}"
# בדיקת חיבור של סכומים שבריים
m3 = Money(0.75, "USD")
m4 = m1 + m3
assert str(m4) == "11.00 USD", f"Addition with fractional amounts failed, got {str(m4)}"
# בדיקת כפל בסקלר שברי
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:
# הפעולות האלה אמורות לפעול ללא שגיאות
m1 = Money(10.0, "USD")
m2 = m1 * 2
m3 = m1 * 2.5
# בדיקת שוויון עם טיפוסים שונים
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():
# בדיקת רגישות לאותיות גדולות וקטנות בקודי מטבע
m1 = Money(10.0, "USD")
m2 = Money(10.0, "usd")
# קודי מטבע צריכים להיות רגישים לאותיות גדולות וקטנות
assert m1 != m2, "Currency comparison should be case-sensitive"
# הוספת מטבעות עם הבדלים באותיות גדולות וקטנות אמורה להיכשל
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():
# צור אובייקטים רבים של Money ובצע פעולות
base = Money(1.0, "USD")
result = base
# בצע 1000 פעולות חיבור
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 פעולות כפל
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!")
# הרץ את הבדיקה המתאימה על סמך הקלט
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}")השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות התכנות מונחה העצמים (OOP)
קבצים חיצונייםמבוא ל-OOPמחלקות לעומת אובייקטיםהפרמטר selfמתודותמאפייניםשיטת הבנאי (__init__)חזרה: מחשבון פשוט5פולימורפיזם
בחינה מחדש של דריסת מתודותטיפוסיות ברווזמחלקות ומתודות אבסטרקטיותעיצוב ממשקיםסיכום – מחשבון צורות8מושגים מתקדמים בתכנות מונחה עצמים
קומפוזיציה לעומת הורשהMixinsמתודות סטטיות ומתודות מחלקהדקורטורים למחלקותמנהלי הקשרתרגלו בעצמכם: קומפיילר Python אונליין