본문 바로가기

프로그래머/Python

[윤성우의 열혈 파이썬 중급편] 27. 연산자 오버로딩

출처 : 윤성우의 열혈 파이썬 : 중급

27. 연산자 오버로딩

# overloading.py
class Account:
    def __init__(self, aid, abl):
        self.aid = aid
        self.abl = abl
    def __add__(self, m):
        self.abl += m
        print('__add__')
    def __sub__(self, m):
        self.abl -= m
        print('__sub__')
    def __call__(self):
        print('__call__')
        return str(self.aid) + ':' + str(self.abl)

def main():
    acnt = Account('James01', 100)
    acnt + 100
    acnt - 50
    print(acnt())   # __call__

main()
  • acnt + 100 => acnt.__add __(100)
  • acnt - 100 => acnt.__sub __(100)
  • acnt() => acnt.__call __()

적절한 형태로 + 와 0 연산자 오버로딩

# vector_add.py
class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __add__(self, o):
        return Vector(self.x + o.x, self.y + o.y)
    def __call__(self):
        return 'Vector({0}, {1})'.format(self.x, self.y)

def main()
    v1 = Vector(3, 3)
    v2 = Vector(7, 7)
    v3 = v1 + v2
    print(v1())
    print(v2())
    print(v3())

main()
  • v1과 v2의 x, y 값을 각각 더한 결과가 담긴 새로운 Vector 객체가 생성되었다

메소드 __str __의 정의

class Simple:
    def __init__(self, i):
        self.i = i
    def __str__(self):
        return 'Simple({0})'.format(self.i)

s = Simple(20)
print(s)    # Simple(20)
# vector_str.py
class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __add__(self, o):
        return Vector(self.x + o.x, self.y + o.y)
    def __str__(self):
        return 'Vector({0}, {1})'.format(self.x, self.y)

def main()
    v1 = Vector(3, 3)
    v2 = Vector(7, 7)
    v3 = v1 + v2
    print(v1)
    print(v2)
    print(v3)

main()

in-place 형태의 연산자 오버로딩

# vector_inp1.py
class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __add__(self, o):
        return Vector(self.x + o.x, self.y + o.y)
    def __str__(self):
        return 'Vector({0}, {1})'.format(self.x, self.y)

def main()
    v1 = Vector(3, 3)
    v2 = Vector(7, 7)
    print(v1, id(v1))
    v1 += v2
    print(v2, id(v2))

main()
  • += 연산 후에 v1에는 다른 객체가 저장된다
  • 파이썬에서는 정수를 담고 있는 변수를 대상으로도 동일한 결과가 나타난다
  • 이는 정수와 문자열이 수정 불가능한 immutable 객체이기 때문이다

__iadd __

# vector_inp1.py
class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __add__(self, o):
        return Vector(self.x + o.x, self.y + o.y)
    def __iadd__(self, o):
        self.x += o.x
        self.y += o.y
        return self
    def __str__(self):
        return 'Vector({0}, {1})'.format(self.x, self.y)

def main()
    v1 = Vector(3, 3)
    v2 = Vector(7, 7)
    print(v1, id(v1))
    v1 += v2
    print(v2, id(v2))

main()
  • += 이나 -= 과 같은 연산잗릉르 가리켜 in-place 연산자라고 한다
  • 그리고 이들 in-place 연산자를 오버로딩 할 때에는 반드시 self를 반환해야 한다

Account 클래스 수정하기

# account.py
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 '{0}, {1}'.format(self.aid, self.abl)

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

main()