초보 개발자

27강 연산자 오버로딩 본문

Python/윤성우 열혈 파이썬

27강 연산자 오버로딩

taehyeki 2022. 1. 24. 22:05

[연산자 오버로딩 간단히 이해하기]

 

연산자 오버로드란 +, - 와 같은 연산자에 다른 기능을 입히는 것을 말한다.

이 Account는 계좌 클래스이고 이 클래스의 메서드로 스페셜 메소드를 주었다. __add__란 

acnt + 100 이라는 구문은

'객체' + '인자' 로 인식을하여 acnt에 __add__라는 것이 있으면 +를 __add__함수로 인식하고 그 오른 쪽에 있는 것을 인자로 인식을 한다.

acnt - 100도 마찬가지이다. acnt 옆에 -가있다면 먼저 acnt가 메서드에 __sub__라는 것이 있나 확인하고 있다면 그 함수를 실행시키는데 그 인자는 오른쪽에 있는 것을 넣는다. 

 

함수호출과 같이 객체에 ()를 붙여서 호출하는 경우 acnt() < 이 객체가 __call__이라는 메서드를 있는지 확인하고 있다고 그 메서드를 호출한다.

acnt + 100 -> acnt.__add__(100)
acnt - 50  -> acnt.__sub__(50)
acnt()     -> acnt.__call__()

 

[적절한 형태로 +와 - 연산자 오버로딩]

n = 10, m = 20 n + m 을 하면 30을 반환한다. 그렇다고해서 n의 값, 혹은 m의 값의 변화가 생기는 것은 아니다.

근데 앞서 보인 예제에서는 그렇게 하지 않았다 + 연산을 하는 경우 acnt에 저장된 객체의 값이 증가하도록 오버로딩이 되어있었다. 

 

따라서 조금 수정해줄 필요가 있다, +=와 -=를 사용하는 것이 적절할 것이다.

class Account:
    def __init__(self,aid,abl):
        self.aid = aid
        self.abl = abl
    def __iadd__(self,m):
        self.abl += m
        return self
    def __isub__(self, m):
        self.abl -= m
        return self
    def __str__(self):
        return f'{self.aid} : {self.abl}'

def main():
    acnt = Account('kim',100)
    acnt += 100
    acnt -= 50
    print(acnt)
main()

 

iadd는 += isub는 -=를 의미한다. 하지만 여기서 주의해야할 것이 있는데 return으로 self를 반환해야한다. 

+=이나 -=과 같은 연산자를 가리켜 in-place연산이라고 한다. 이들은 오버로딩 할 때 반드시 self를 반환해야한다 

파이썬은 +=연산을 다음과 같이 처리하기 때문이다

 

v1 += v2 => v1 = v1.__iadd__(v2)
따라서 self를 반환하지 않으면 연산은 잘해놓고 v1은 텅 비는 상태가 될 수있다.

 

 

 

 

 

 

 

아래와 같은 코드를 입력하면 아래의 출력화면이 나온다.

class Account:
    def __init__(self, i):
        self.i = i

a = Account(10)
print(str(a))
print(a)

<__main__.Account object at 0x000002B0972713A0>
<__main__.Account object at 0x000002B0972713A0>

 

이걸 i의 값을 반환하도록 오버라이딩을 해주고 싶다면 아래와 같이 __str__메서드를 오버라이딩 해주자

print는 __str__메소드가 반환하는 문자열을 출력한다.

class Account:
    def __init__(self, i):
        self.i = i
    def __str__(self):
        return str(self.i)

a = Account(10)
print(str(a))
print(a)

10
10

 

 

 

 

'Python > 윤성우 열혈 파이썬' 카테고리의 다른 글

29강 __slots__의 효과  (0) 2022.01.25
28강 정보은닉과 __dict__  (0) 2022.01.24
26강 스페셜 메소드  (0) 2022.01.18
24강 상속  (0) 2022.01.18
23강 클래스와 객체의 본질  (0) 2022.01.18