dunder 메서드("double underscore", 매직/특수 메서드라고도 함)는 __init__, __str__, __len__ 같이 특별하게 명명된 메서드로, 객체가 Python의 와 통합되게 합니다. Python은 문법에 반응하여 이들을 자동으로 호출합니다 — 예를 들어 는 을 호출합니다.
len(obj)obj.__len__()class Vector:
def __init__(self, x, y): # 생성자 — Vector(1, 2)
self.x, self.y = x, y
def __repr__(self): # repr(v)와 REPL — 개발자용
return f"Vector({self.x}, {self.y})"
def __str__(self): # str(v) / print(v) — 사용자용
return f"({self.x}, {self.y})"
def __add__(self, other): # + 연산자를 활성화: v1 + v2
return Vector(self.x + other.x, self.y + other.y)
def __eq__(self, other): # ==를 활성화
return self.x == other.x and self.y == other.y
v1, v2 = Vector(1, 2), Vector(3, 4)
v1 + v2 # Vector(4, 6) — __add__ 호출
print(v1) # (1, 2) — __str__ 호출
v1 == Vector(1, 2) # True — __eq__ 호출
이들을 정의하면 사용자 정의 객체가 내장 타입처럼 네이티브 문법(+, ==, print)과 함께 동작하게 됩니다.
__init__ → 생성자 (객체 생성)
__repr__ → 모호하지 않은 개발자 표현 (디버깅, REPL)
__str__ → 읽기 쉬운 사용자 대상 문자열 (print, str())
__len__ → len(obj)
__getitem__→ obj[key] (인덱싱/서브스크립팅)
__iter__ / __next__ → 객체를 iterable로 만듦 (for 루프)
__eq__, __lt__, __gt__ → 비교 연산자 (==, <, >)
__add__, __sub__, __mul__ → 산술 연산자
__call__ → 인스턴스를 함수처럼 호출 가능하게 만듦: obj()
__contains__ → `in` 연산자
__enter__ / __exit__ → context manager (with 문)
class Deck:
def __init__(self): self.cards = [...]
def __len__(self): return len(self.cards) # len(deck)
def __getitem__(self, i): return self.cards[i] # deck[0], 그리고 반복/슬라이싱!
deck = Deck()
len(deck) # 동작함
for card in deck: # __getitem__이 이것도 iterable하게 만듦
...
__len__과 __getitem__을 구현하면 객체가 시퀀스처럼 동작합니다 — len(), 인덱싱, 반복, 슬라이싱을 지원합니다.
dunder 메서드는 Python이 일관된 "모든 것은 객체" 느낌을 달성하는 방법입니다 — 사용자 정의 클래스가 언어의 연산자 및 내장 함수(+, ==, len(), for, [], with, print)와 매끄럽게 통합되게 합니다.
이것이 Python의 우아하고 다형적인 설계("덕 타이핑" + 데이터 모델)의 기반입니다.
핵심 dunder들 — 특히 __init__, __repr__/__str__, 비교 및 산술 연산자, 반복 프로토콜 — 을 알면 네이티브 타입처럼 느껴지는 직관적이고 Pythonic한 클래스를 만들 수 있으며, 언어의 문법이 내부적으로 메서드 호출에 어떻게 매핑되는지 설명해 줍니다.