Operator Overloading 1편:
https://jiwonkoh.tistory.com/48
<목차>
▶ (문제) 두 개의 클래스 객체의 알파벳이 같으면 비교연산자 ==가 True다!
▶ (추가문제) 클래스 객체를 iterable하게 만드려면?
▶ iterator와 iterables의 차이
▶ (문제) 두 개의 클래스 객체의 알파벳이 같으면 비교연산자 ==가 True다!
이런 문제는 어떻게 풀 수 있을까?
클래스 객체 두 개를 만들고, 그 객체 안에 있는 알파벳 수가 같으면, ==가 True도록 하는 것이다.
이 문제도 Operator Overloading을 이용해서 풀 수 있다.
앞에서 보았듯이, 비교연산자의 Dunder method는 __eq__(self, other)이다.
이를 클래스 안에 넣어서 ==를 재정의해주면 되겠구나!.. 싶었지만..
class my_class:
def __init__(self, letter):
self.index = 0
self.letter = letter
def __eq__(self, other):
num1 = sum(x.isalpha() for x in self)
num2 = sum(y.isalpha() for y in other)
return True if num1 == num2 else False
a = my_class('abc123')
b = my_class('def456')
print(a == b)
# False
그렇다면 이 코드만 클래스에 추가해주면 될까? 답은 No이다. 왜냐하면 본인이 만든 클래스 객체는 iterable하지 않기 때문이다.
파이썬의 내장 자료형으로는 쉽게 써온 for문을 돌릴 수 없다는 것이다.
▶ (추가문제) 클래스 객체를 iterable하게 만드려면?
클래스 객체를 iterable하게 하려면 다음과 같이 짜야한다.
class my_class:
def __init__(self, letter):
self.index = 0
self.letter = letter
def __iter__(self):
return self
def __next__(self):
try:
result = self.letter[self.index]
except IndexError:
raise StopIteration
self.index += 1
return result
def __eq__(self, other):
num1 = sum(x.isalpha() for x in self)
num2 = sum(y.isalpha() for y in other)
return True if num1 == num2 else False
a = my_class('abc123')
b = my_class('def456')
print(a == b)
# True
하나씩 살펴보자.
def __init__(self, letter):
self.index = 0
self.letter = letter
→ 클래스의 생성자이다. iterator을 만드는데 쓸 index 변수를 만들고, self.letter라는 인스턴스 변수를 만든다.
def __iter__(self):
return self
def __next__(self):
try:
result = self.letter[self.index]
except IndexError:
raise StopIteration
self.index += 1
return result
→ 객체를 iterable하게 만들기 위해서는 두가지 메소드를 사용한다. __iter__()과 __next__()이다.
이 두가지를 합친 것을 iterator protocol이라고 한다.
두 메소드의 역할을 알기 위해서는 iterator와 iterables의 차이를 알아야한다.
▶ iterator와 iterables의 차이
(1) Iterables란?
반복할 수 있는 것을 뜻한다. 대부분 요소를 담고있는 컨테이너를 말하는데, 리스트, 튜플, 딕셔너리가 예시이다.
(2) Iterator란?
iterable을 반복하기 위해서는 iterator을 써야한다. iterator란 반복문을 작동할 수 있게 해주는 객체이다.
리스트를 반복하는 경우에, iterator는 현재 어디를 반복하고 있는지 추적해준다.
(1) __iter__()의 역할?
iterator 객체로 바꾸어 리턴하고, 반복문의 시작에 호출된다. = 반복할 객체를 부른다고 생각하면 쉽다.
(2) __next__()의 역할?
객체의 다음 값을 반환하고, 반복문이 시작된 다음에 호출된다. 더 이상 리턴할 값이 없는 경우에 StopIteration 예외가 발생한다. 이 에러는 반복문의 반복을 멈추는 데 사용한다.
'Computer Science > [20-3,4] Python Basic' 카테고리의 다른 글
[Python] 복사본 변수의 변경이 원본에 영향을 미칠 때 (0) | 2020.04.03 |
---|---|
[Python] Operator Overloading (3) 클래스 객체 간의 연산과 역순 연산자 (0) | 2020.04.02 |
[Python] Operator Overloading (1) == 연산자 재정의하기 (0) | 2020.04.01 |
[Python] Optional Parameter에 None 주의해서 쓰기 (0) | 2020.04.01 |
[Python] 클래스 상속 (Class Inheritance)란? (0) | 2020.04.01 |
댓글