<목차>
① (예시) + 연산자에 대한 설명
② 역순 연산자의 이해
③ 순서가 있는 연산자의 역순 연산자를 쓸때
class Number:
def __init__(self, number):
self.number = number
n1 = Number(1)
n2 = Number(1)
print(n1 + n2)
# TypeError: unsupported operand type(s) for +: 'Number' and 'Number'
print(n1 + 100)
# TypeError: unsupported operand type(s) for +: 'Number' and 'int'
여기 아주 간단한 클래스 Number가 있다. 생성자 메소드만을 포함하고 있다.
파이썬에서 본인이 만든 클래스의 객체끼리 연산자를 사용할 수 없다.
또 클래스의 객체와 다른 빌트인 객체 간이 연산도 되지 않는다.
① (예시) + 연산자에 대한 설명
o1 + o2
파이썬에서 이러한 더하기 연산을 하려고 하면,
type(o1).__add__(o1, o2)
의 형식으로 바꿔주어야 한다.
아래의 예시를 보면,
class Number:
def __init__(self, number):
self.number = number
n1 = Number(1)
n2 = Number(1)
print(type(n1))
# <class '__main__.Number'>
print(type(10))
# <class 'int'>
print(n1 + 10)
# TypeError: unsupported operand type(s) for +: 'Number' and 'int'
→ type() 함수는 객체의 데이터 타입을 확인할 수 있는 함수이다. 이 함수를 통해서,
n1은 __main__.Number의 인스턴스이고, 10은 int 클래스의 인스턴스임을 확인할 수 있다.
이제 더하기 연산을 실행한다고 생각해보자,
n1 + 10 은
type(n1).__add__(n1, 10) 으로 실행이 되는데,
n1의 클래스인 Number에는 __add__()라는 Dunder Method가 존재하지 않는다.
따라서 이 연산을 수행하기 위해, Number 클래스에 __add__()를 추가해보자.
class Number:
def __init__(self, number):
self.number = number
def __add__(self, other):
return self.number + other
n1 = Number(1)
n2 = Number(1)
print(n1 + 10)
# 11
→ 원하는 대로 실행이 되었다! 하지만 여기서 문제는 반대의 경우,
10 + n1 이 작동하지 않는다.
이 연산은 type(10).__add__(10, n1) 으로 실행이 되는데,
이렇게 인스턴스 객체가 오른쪽으로 이동하면 __radd__() 가 호출이 된다.
하지만 우리가 만든 클래스 안에 __radd__()가 존재하지 않으니, 추가해주면 된다.
class Number:
def __init__(self, number):
self.number = number
def __add__(self, other):
return self.number + other
def __radd__(self, other):
return self.number + other
n1 = Number(1)
n2 = Number(1)
print(10 + n1)
② 역순 연산자의 이해
위에서 사용한 __radd__()의 이름은 역순 연산자이다.
기존 연산자의 Dunder Method 앞에 'r'을 붙여주면 역순 연산자가 된다.
이 연산자는 right operand로, 인스턴스 객체가 오른쪽에 있을 때 쓰인다.
__radd__()는 파이썬이 left operand __add__() 호출을 실패하면 시도하고, 인자의 순서를 바꿔서 연산한다.
③ 순서가 있는 연산자의 역순 연산자를 쓸때
//, **, %, - 등 순서가 중요한 연산자를 사용할 때에는 역순 연산자의 리턴값에 주의한다.
# correct
class Number:
def __init__(self, number):
self.number = number
def __sub__(self, other):
return self.number - other
def __rsub__(self, other):
return other - self.number
n1 = Number(1)
n2 = Number(1)
print(n1 - 100)
# -99
print(100 - n1)
# 99
# wrong
class Number:
def __init__(self, number):
self.number = number
def __sub__(self, other):
return self.number - other
def __rsub__(self, other):
return self.number - other
n1 = Number(1)
n2 = Number(1)
print(n1 - 100)
# -99
print(100 - n1)
# -99 # Wrong!
'Computer Science > [20-3,4] Python Basic' 카테고리의 다른 글
[Python] csv 파일에서 특정 단어를 가진 열 찾아보기 (0) | 2020.04.22 |
---|---|
[Python] 복사본 변수의 변경이 원본에 영향을 미칠 때 (0) | 2020.04.03 |
[Python] Operator Overloading (2) iterator 구현해보기 (0) | 2020.04.02 |
[Python] Operator Overloading (1) == 연산자 재정의하기 (0) | 2020.04.01 |
[Python] Optional Parameter에 None 주의해서 쓰기 (0) | 2020.04.01 |
댓글