연산자 오버로딩 — 각 심볼이 부르는 거
Python 의 모든 연산자가 dunder 매핑. + 가 __add__. - 가 __sub__. * 가 __mul__. < 가 __lt__. 전체 list 는 data model 에. 구현하면 커스텀 Vector 클래스에 v1 + v2 가능. Reflected 버전 (__radd__ 등) 은 클래스가 연산자 오른쪽에 있고 왼쪽이 다른 타입일 때.
컨테이너 dunder — len / getitem / contains / iter
__len__ 이 len(obj) 작동시켜. __getitem__ 이 obj[i]. __contains__ 가 x in obj. __iter__ 가 for x in obj. 정수 인덱스로 __getitem__ 구현하면 — 무료로 반복도. Python 이 __getitem__(0), __getitem__(1), ... IndexError 까지 fallback.
__bool__ — 객체의 truthiness
__bool__ 없으면 Python 은 __len__ 정의됐으면 사용 (길이 0 이 falsy), 아니면 모든 인스턴스 truthy. 둘 다 디폴트 안 맞을 때 __bool__ 정의. 메서드는 bool 반환해야.
__call__ — 인스턴스를 함수처럼
__call__ 정의 + my_instance(args) 가능. 어디서나 사용 — 클래스 기반 decorator, state 가진 함수 객체, callable 전략. decorators 트랙에서 봤어.
원칙: 연산자 오버로딩은 연산이 타입에 자연스러운 의미일 때 좋아 (Vector + Vector, Money + Money). 강제하거나 모호할 때 나빠 (User + User?). 편향 — 독자가 타입만 봐서
a + b 가 뭐 할지 못 예측하면 — 오버로드 X.