매직 메서드
1. 매직 메서드
파이썬의 클래스에는 기본적으로 내장하고 있는 특별 메서드들이 있습니다. 파이썬에서는 이런 내장하고 있는 특별 메서드들을 쉽게 재정의하여 사용할 수 있게 되어있습니다.
마치 마법처럼 간단하게 수정할 수 있다고 해서 매직 매서드라고 부릅니다. 혹은 더블 언더바(__)를 2개 쓰고 있는 점에서 던더(dunder) 메서드라고도 부릅니다.
좌표평면의 점을 class로 구현해보았습니다. 우선 간단한 예제로 __add__
를 살펴보도록 하겠습니다.
+
부호를 사용하여 덧셈을 할 때 dot1의 __add__
메직메서드가 실행됩니다. print로 self의 x좌표와 y좌표를 출력함으로 알 수 있습니다.
매직 메서드 __init__
은 앞에서도 살펴보았습니다. 이 매직 메서드는 인스턴스가 생성이 될 때 호출됩니다. 위 코드에서는 dot1과 dot2 인스턴스가 생성이 될 때 호출됩니다. 여기서 (10, 20)
, (20, 30)
은 각각 인스턴스의 영역 self에 등록됩니다.
마찬가지로 곱하기도 구현할 수 있습니다. 곱하기는 __mul__
로 구현할 수 있습니다. 다만 실제 곱하기를 구현하지는 않았습니다. 이는 실제 곱하기를 구현하지 않아도 된다는 것을 보여드리기 위함입니다.
이번에는 행렬의 연산을 구현한 예시로 살펴보도록 하겠습니다.
위와 같은 예시를 통해 행렬의 덧셈, 뺄셈, 곱셈 등을 구현할 수도 있습니다.
이렇게 부호들은 클래스의 메직메서드와 연결되어 있습니다. 연산에 관련된 매직 메서드 공식 문서는 아래와 같습니다. 이러한 매직 메서드의 종류는 너무도 많기 때문에 필요에 따라 찾아보며 코딩합니다. 주요한 메서드는 아래 챕터에서 정리하도록 하겠습니다.
Data model (매직 메서드)2. 주요한 매직 메서드
2.1. 생성자와 소멸자
__init__(self, ...)
: 객체가 생성될 때 호출되는 생성자 메서드__del__(self)
: 객체가 소멸될 때 호출되는 소멸자 메서드
2.2. 문자열 표현
__str__(self)
:str()
함수 출력 결과와 같습니다. 이는 print로 출력되는 결과와도 동일합니다. 이 출력은 "공식적이지 않은" 또는 "좋게 보이는" 문자열 표현을 반환합니다. 객체의 공식적인 표현은 repr입니다.__repr__(self)
:repr()
함수의 출력 결과와 같습니다. 객체의 "공식적인" 문자열 표현을 반환합니다.
2.3. 산술 연산
__add__(self, other)
: 덧셈 연산__sub__(self, other)
: 뺄셈 연산__mul__(self, other)
: 곱셈 연산__truediv__(self, other)
: 나눗셈 연산(/)
2.4. 비교 연산
__eq__(self, other)
: 동등 연산 (==)__ne__(self, other)
: 부등 연산 (!=)__lt__(self, other)
: "작다" 연산 (<)__le__(self, other)
: "작거나 같다" 연산 (<=)__gt__(self, other)
: "크다" 연산 (>)__ge__(self, other)
: "크거나 같다" 연산 (>=)
2.5. 컨테이너 타입 연산
__len__(self)
:len()
함수의 출력 결과와 같습니다.__getitem__(self, key)
: 인덱싱 연산 (obj[key])의 출력 결과와 같습니다.__setitem__(self, key, value)
: 항목 할당__contains__(self, value)
:in
연산자
2.6. 호출 가능 객체
__call__(self, ...)
: 객체를 함수처럼 호출할 때 사용됩니다.
이 밖에도 많은 매직 메서드들이 있습니다. 이 메서드들을 오버라이드하여 사용자 정의 클래스의 동작을 원하는 대로 정의할 수 있습니다.
3. 매직 메서드 __call__
과 __getitem__
예시
매직 메서드 __call__
이나 __getitem__
과 같은 형태는 어떻게 동작하는지 예시를 보지 않으면 그 사용법을 알기 힘듭니다. 어떻게 동작하는지 예시를 통해 보도록 하겠습니다.
위 코드에서 __call__
이 있기 때문에 인스턴스는 마치 함수처럼 호출할 수 있게 됩니다. 괄호의 형태로요. 그때마다 10이 더해지고 현재값을 출력합니다. return은 생략되어 있기 때문에 None입니다. 때문에 print를 했으면 None이 출력되었을 것입니다.
__getitem__
이 있기 때문에 대괄호 안에 값을 넣어 출력할 수 있습니다. 대괄호 안에는 숫자 뿐만 아니라 문자나 객체가 들어갈 수도 있습니다. 이를 통해 좀 더 유연한 자료형을 만들 수도 있습니다.