클래스를 언어와 통합시키는 메서드들
Dunder 메서드 (이중 언더스코어) 가 Python 빌트인 연산이 클래스와 대화하는 방식. print(obj) 가 obj.__str__ 호출. obj1 == obj2 가 __eq__ 호출. {obj: 1} 가 __hash__ 호출. 적절한 dunder 구현이 클래스를 native Python 타입처럼 동작하게.
__repr__ vs __str__ — 명확한 거 vs 친근한 거
__repr__ 은 명확해야 — 이상적으론 평가하면 객체 재생성하는 문자열 — Point(x=3, y=4). REPL 과 디버거 출력에서 보여. __str__ 은 친근한, 사용자용 문자열 — print 와 str(obj) 가 사용. 하나만 정의하면 __repr__ — Python 이 __str__ 없으면 fallback.
__eq__ — 값 동등성
디폴트 — obj1 == obj2 가 identity (obj1 is obj2). __eq__ override 해서 값으로 비교 — 보통 관련 속성 비교. 두 Point(3, 4) 인스턴스는 다른 객체라도 equal 해야.
__hash__ — dict 키나 set 멤버 되려면 필수
__eq__ override 하면 Python 이 __hash__ 를 None 으로 — 인스턴스 hashable 안 됨. 이유 — Python 의 계약 = equal 객체는 같은 hash. 하나 override 하면 일관성 유지해야. 해결책 — __eq__ 와 함께 __hash__ 정의, 보통 hash((self.attr1, self.attr2)). mutable 객체엔 종종 __hash__ 를 None 으로 두는 게 맞음 — mutable 은 hash 안 되어야.
__repr__ (디버깅), __eq__ (값 비교), __hash__ (컬렉션 멤버십). 그 순서로 함께 정의 — 클래스가 언어에 깔끔히 통합. 또는 @dataclass 써서 자동 생성 (lesson 6).