파이썬과 객체지향 프로그래밍 - 연산자 중복 정의(Operator Overloading)

9. 연산자 중복 정의(Operator Overloading)

  • 객체에서 필요한 연산자를 재정의하는 것
  • 연산자 중복을 위해 미리 정의된 특별한 메서드 존재: __로 시작 __로 끝나는 특수 함수
  • 해당 메쏘드들을 구현하면, 객체에 여러가지 파이썬 내장 함수나 연산자를 재정의하여 사용 가능
  • https://docs.python.org/3/reference/datamodel.html

Quadrangle + Figure = Quadrangle(widths, heights)

In [233]:
class Figure:
    def __init__(self, width, height):
        self.width = width
        self.height = height        
In [ ]:
class Quadrangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def __add__(self, second):    
        return Quadrangle(self.width + second.width, self.height + second.height)
In [237]:
rectangle1 = Quadrangle(2, 3)
figure1 = Figure(3, 4)
rectangle2 = rectangle1 + figure1
rectangle2.width
Out[237]:
5
In [234]:
class Quadrangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def __add__(self, second):    
        return Quadrangle(self.width + second.width, self.height + second.height)
    
    # 연산자 곱셈    
    def __mul__(self, num):
        return Quadrangle(self.width * num, self.height * num)

    # 연산자 len() - 길이    
    def __len__(self):
        return self.width ** 2 + self.height ** 2

    # 연산자 A[index] - 리스트    
    def __getitem__(self, index):
        if index == 0:
            return self.width
        elif index == 1:
            return self.height

    # 연산자 str() - 문자열 변환           
    def __str__(self):
        return 'width : {}, height : {}'.format(self.width, self.height)
In [236]:
rectangle1 = Quadrangle(2, 3)
figure1 = Figure(3, 4)
rectangle2 = rectangle1 + figure1
rectangle2.width
Out[236]:
5
In [231]:
rectangle1 = Quadrangle(2, 3)
rectangle3 = rectangle1 + 4
print (rectangle3.width)
print(rectangle3.width, rectangle3.height)
rectangle4 = rectangle1 * 3
print(str(rectangle1))
print(str(rectangle4))
print(rectangle2[0], rectangle2[1])
print(len(rectangle1))
6
6 7
width : 2, height : 3
width : 6, height : 9
4 6
13
In [232]:
rectangle1 = Quadrangle(3, 4)
rectangle2 = Quadrangle(4, 6)


초간단 연습11
아래 코드를 실행시키면서, 위 코드의 주석을 확인하며, 출력 값이 왜 이렇게 나왔는지 이해하기(연산자 오버로딩 이해)

객체 주소 확인하기와 is, == 연산자 이해하기 (심화)

  • id(객체명): 객체가 가리키는 실제 주소값

  • is 와 == 연산자 차이

    • is : 가리키는 객체 자체가 같은 경우 True
    • == : 가리키는 값들이 같은 경우 True
In [137]:
class Figure(Quadrangle):
    pass

rectangle1 = Quadrangle(1, 2)
rectangle2 = Quadrangle(1, 2)
rectangle3 = rectangle1
print (id(rectangle1))
print (id(rectangle2))
print(rectangle1 is rectangle2)
print(rectangle1 is rectangle3)
print(rectangle1 == rectangle2)
print(rectangle1.width == rectangle2.width)
4587949136
4587759264
False
True
False
True
한발짝 더 나가보기!(심화 문제)
아래 코드를 실행시키면서, 위 코드 결과와 비교하며, 출력 값이 왜 이렇게 나왔는지 이해하기(연산자 오버로딩 이해)
In [138]:
class Figure(Quadrangle):
    # 연산자 == 
    def __eq__(self, p):
        if ((self.width == p.width) and (self.height == p.height)):
            return True
        else:
            return False

rectangle1 = Figure(1, 2)
rectangle2 = Figure(1, 2)
rectangle3 = rectangle1
print (id(rectangle1))
print (id(rectangle2))
print(rectangle1 is rectangle2)
print(rectangle1 is rectangle3)
print(rectangle1 == rectangle2)
print(rectangle1.width == rectangle2.width)
4587966248
4587966136
False
True
True
True
협업 과제(남에게 설명하면, 자신이 배운답니다.!)
사전조건: Keyword 클래스를 생성
- 클래스 인자로 영어 단어 한 개를 받습니다.
- attribute: 영어 단어
- method: 연산자 오버로딩 - len() : 영어 단어 길이 리턴
프로그래밍 1. Keyword 클래스로 10개의 임의 영어 단어를 가지고 각각 객체로 만들어서 하나의 리스트에 넣습니다.(위 예 참조)

2. 영어 단어 길이를 기준으로 리스트를 정렬하기
- \__len\__(self) 정의하기
- sorted 함수와 lambda 로 길이 순 정렬 기법

3. 영어 단어의 두 번째 알파벳을 기준으로 리스트를 정렬하기
- \__getitem\__(self, key) 정의하기

- 참고: sorted 함수와 lambda 로 리스트 정렬 기법
- 구글로 필요한 부분을 찾는 역량을 길러야 합니다. https://wayhome25.github.io/python/2017/03/07/key-function/
리스트변수명 = sorted(리스트변수명, key=lambda x:len(x))
In [104]:
class Keyword:
    def __init__(self, word):
        self.word = word

    # 연산자 len() - 길이    
    def __len__(self):
        return len(self.word)

    # 연산자 A[index] - 리스트    
    def __getitem__(self, index):
        return self.word[index]

    def get_word(self):
        return self.word

hi = Keyword('hi')
hello = Keyword('hello')
bye = Keyword('bye')
len(hi)
keywords = [hi, hello, bye]

keywords = sorted(keywords, key=lambda x:len(x))

for keyword in keywords:
    print (keyword.get_word())

keywords = sorted(keywords, key=lambda x:x[1])

for keyword in keywords:
    print (keyword.get_word())
hi
bye
hello
hello
hi
bye
In [249]:
class Keyword:
    def __init__(self, word):
        self.keyword = word

    def __len__(self):
        return len(self.keyword)

key1 = Keyword('hi')
key2 = Keyword('hello')
key3 = Keyword('bye')


In [250]:
keywords = [key1, key2, key3]
keywords = sorted(keywords, key=lambda x:len(x))
for keyword in keywords:
    print (keyword.keyword)
hi
bye
hello
In [251]:
class Keyword:
    def __init__(self, word):
        self.keyword = word

    def __getitem__(self, index):
        return self.keyword[index]

key1 = Keyword('hi')
key2 = Keyword('hello')
key3 = Keyword('bye')
In [252]:
keywords = [key1, key2, key3]
keywords = sorted(keywords, key=lambda x:x[1])
for keyword in keywords:
    print (keyword.keyword)
hello
hi
bye