[Py: Class] 5.연산자 오버로딩(Operator Overloading)
연산자 오버로딩(Operator Overloading)
연산자 오버로딩(Operator Overloading)
은 프로그래밍에서 사용자가 직접 정의한 클래스 객체에+
,-
,*
와 같은 일반 연산자의 기능을 재정의하여 연산 가능한 상태로 만드는 기법이다.
예를 들어, 복소수(Complex) 객체에서 필요한
+
연산을 아래와 같이__add__
메소드를 통해서 재정의(오버로딩) 할 수 있다.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
class Complex: def __init__(self, real, imag): self.real = real self.imag = imag # + 연산자 오버로딩 def __add__(self, other): return Complex(self.real + other.real, self.imag + other.imag) def __str__(self): return f"{self.real} + {self.imag}i" a = Complex(1, 2) b = Complex(2, 3) c = a + b # + 연산자 오버로딩을 사용한 덧셈 print(c) # 출력: 3 + 5i
in-place 형태의 연산자 오버로딩
(1) in-place 연산자란?
- 다음의 예제의 경우, 연산을 진행해도 피연산자 n1과 n2의 값의 변화는 없다.
1 2 3
n1 = 30 n2 = 50 n3 = n1+n2
- 하지만, 우측의 예제에서는 연산을 진행할 경우 피연산자 n2의 값이 변경된다.
1 2 3
n1 = 30 n2 = 50 n2 += n1
- 이때, 우측과 같이 피연산자의 원본을 수정하는 연산자(
+=, -= 등
)를inplace-연산자
라고 한다. 그러므로, in-place 형태의 연산자 오버로딩은 피연산자의 변화를 유도하는 오버로딩을 의미함을 알 수 있다.
(2) in-place 연산자 오버로딩
+=
이나-=
를 포함한 in-place연산자의 스페셜 메소드는 다음과 같다.+=
:__iadd__(self, other)
-=
:__isub__(self, other)
*=
:__imul__(self, other)
/=
:__itruediv__(self, other)
위와 같은 in-place연산자를 오버로딩하기 위해서는 아래와 같이 반드시
self
반환을 수행해야 한다. (*이는 공식처럼 기억해야만 한다.)1 2 3 4 5 6
def __iadd__(self, o): self.x += o.x self.y += o.y return self v1 += v2 # 해당 연산시 위의 class 메소드 수행됨
- 왜냐하면,
v1.__iadd__(v2)
에 의해 계산된 바른 값이 return되지 않았을 경우 다음과 같이 None이 반환되어 피연산자의 원본이 올바르게 수정되지 않기 때문이다.1 2 3 4 5 6
def __iadd__(self, o): self.x += o.x self.y += o.y #return vector(self.x, self.y) 혹은 self v1 += v2 # None
immutable & mutable 객체
- in-place연산자의 동작은 대상 객체가
immutable
인지mutable
인지에 따라 달라진다.
immutable
객체- 정수, 문자열, 튜플이 해당된다.
- 특정 주소에 한 번 생성된 내용을 변경할 수 없는 객체이다.
- in-place 연산자를 해당 객체에 사용하면 기존 객체가 저장된 주소와 다른 주소에 새로운 값을 저장한다.
1 2 3 4 5 6 7
x1 = 10 before_id1 = id(x1) x1 += 20 after_id1 = id(x1) print(before_id1 == after_id1) # False
mutable
객체- 리스트, 딕셔너리, 집합이 해당된다.
- 특정 주소에 생성된 내용을 변경할 수 있는 객체이다.
- in-place 연산자를 해당 객체에 사용하면 원래의 객체가 직접 수정된다.
1 2 3 4 5 6 7
x2 = [10] before_id2 = id(x2) x2 += [20] after_id2 = id(x2) print(before_id2 == after_id2) # True
위의 객체들을 이용해서 사용자 지정 클래스 객체의 경우 프로그래머가 프로그램의 내용에 따라서 immutable한 성격을 가지게 할 것인지 혹은 mutable한 성격을 가지게할 것인지 결정할 수 있다. 예를 들면 다음과 같다.
immutable 권장 케이스: 판매 날짜, 상품 ID, 판매량, 단가 등이 포함된 판매 건별 매출 정보
mutable 권장 케이스: 은행 계좌에서는 잔액을 입금하거나 출금하는 등의 작업
References
- 윤성우, 『윤성우의 열혈 파이썬 중급편』, ORANGE MEDIA(2021)
This post is licensed under CC BY 4.0 by the author.