연산자 오버로딩
Coddy Python 여정의 Object Oriented Programming 섹션에 포함된 레슨 — 64개 중 34번째.
연산자 오버로딩을 사용하면 특수한 매직 메서드를 구현하여 클래스가 파이썬의 내장 연산자(+, -, *, 등)와 함께 작동하도록 할 수 있습니다.
다음은 연산자 오버로딩을 사용한 클래스의 예입니다:
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__ (==)와 같은 매직 메서드를 사용하여 객체에서 연산자가 작동하는 방식을 정의합니다. 이를 통해 클래스가 파이썬의 내장 연산자와 자연스럽게 동작하게 됩니다.
챌린지
중급이 챌린지에서는 강력한 연산자 오버로딩을 사용하여 화폐 금액을 나타내는 Money 클래스를 구현합니다. 여러분의 구현은 포괄적인 테스트 스위트를 통해 철저히 테스트될 것입니다.
money.py- 이 파일은 여러분이 수정해야 할 유일한 파일입니다. 구현을 안내하는 TODO 주석이 포함된 클래스 정의가 들어 있습니다.driver.py- 구현을 검증하는 광범위한 테스트 시나리오가 포함되어 있습니다 (수정하지 마세요).
다음 기능을 갖춘 Money 클래스를 구현하세요:
amount(float)와currency(string)를 인자로 받는 생성자- 동일한 통화를 가진 Money 객체 간의 덧셈 (
+) - 금액을 배수로 늘리기 위한 숫자와의 곱셈 (
*) - Money 객체 간의 동등성 비교 (
==) - "X.XX CUR" 형식의 문자열 표현
치트 시트
연산자 오버로딩을 사용하면 특별한 매직 메서드를 구현하여 클래스가 파이썬의 내장 연산자와 함께 작동하도록 할 수 있습니다:
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})"연산자 오버로딩을 위한 일반적인 매직 메서드:
+연산자를 위한__add__-연산자를 위한__sub__*연산자를 위한__mul__==연산자를 위한__eq__- 문자열 표현을 위한
__str__
사용 예시:
v1 = Vector(2, 3)
v2 = Vector(5, 7)
result = v1 + v2 # v1.__add__(v2)를 호출합니다
scaled = v1 * 3 # v1.__mul__(3)를 호출합니다
print(v1 == v2) # v1.__eq__(v2)를 호출합니다직접 해보기
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():
# 금액이 0인 경우 테스트
m1 = Money(0.0, "USD")
assert str(m1) == "0.00 USD", f"Zero amount string representation failed, got {str(m1)}"
# 0과의 덧셈 테스트
m2 = Money(10.0, "USD")
m3 = m1 + m2
assert str(m3) == "10.00 USD", f"Addition with zero failed, got {str(m3)}"
# 0과의 곱셈 테스트
m4 = m2 * 0
assert str(m4) == "0.00 USD", f"Multiplication by zero failed, got {str(m4)}"
# 금액이 0일 때의 동등성 테스트
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}")이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.