파이썬은 기본적으로 데이터모델에 적용되는 API가 있다. 모든 클래스에 대하여 길이를 얻도록 설계된 __len__
같은 메서드나 n번째 원소를 얻도록 설계된 __getitem(n)__
같은 메서드가 있다. 모든 클래스에 대하여 이러한 함수를 선언해두면 파이썬에서 알아서 적절하게 이 함수를 호출해서 사용한다. 이러한 메서드는 항상 이름 앞뒤에 언더바가 2개씩 있고, 매직 메서드, 특별 메서드, 던더 메서드라 부른다. 이 외에도 아래와 같은 상황에 해당하는 던더 메서드가 있다.
중요 키워드
던더 메서드, __len__
, __getitem__
, __contains__
__repr__
, __str__
, __bool__
, __iter__
, __add__
, __mul__
, __abs__
, !r, %r
덜 중요한 키워드
doctest: +ELLIPSIS
!s, !a, %s, %a, __rmul__
메타객체, 메타객체 프로그래밍
객체 instance에 __len__
함수가 구현되어있으면 len(instance)
를 통해 길이를 구할 수 있다. 객체 instance에 __getitem__
함수가 구현되어있으면 instance[i]
를 통해 i번째 원소를 얻을 수 있다. 이때 __getitem__
함수가 구현되면 자동으로 파이썬에서 기본으로 제공하는 음수 인덱싱, 슬라이싱을 이용할 수 있고 __len__
과 __getitem__
이 모두 구현되어있으면 random 패키지의 choice함수를 통해 무작위 원소를 고르거나 key함수가 주어진 sort함수를 이용할 수 있고 in
을 통해 존재유무를 확인할 수 있다. in
은 __contains__
가 구현되어있을 경우 이 함수로 대체되어 실행된다.
던더메서드는 파이썬 API가 호출한다. __init__
메서드 안에서 부모 클래스의 초기화를 하거나 메타프로그래밍을 하는 상황이 아니면 던더메서드를 직접 호출하지 않는게 좋다. __iter__
는 range based for문을 돌 때 암묵적으로 호출되게 되는데, 이와 같이 암묵적으로 호출되는 던더메서드도 있다. 내장 자료형들의 __len__
과 같은 일부 던더메서드는 성능 향상을 위해 len
을 호출하지 않고 바로 값을 반환한다. __repr__
는 개발자가 보기 쉽게, __str__
는 사용자가 보기 쉽게 쓰여진 문자열을 출력하도록 함수를 짜야한다. %string에서는 %r을 통해 __repr__
의 결과를 formatting할 수 있고 format string에서는 !r을 통해, fstring에서도 :없이 !r을 통해 할 수 있다. __str__
는 구현되지 않을 경우 __repr__
를 대신 호출하기 때문에 하나만 구현할 경우 __repr__
을 구현하는게 좋다. 일반적으로 __add__
나 __mul__
과 같은 중위연산자들은 객체를 새로 만들어 반환한다. 두 피연산자에는 변환이 없어야 한다. 또한 교환법칙의 성립을 위해 __rmul__
와 같은 함수를 선언할 수도 있다. __bool__
은 객체가 if문에 들어가거나 not, or, and, xor같은 연산자를 만났을 때 bool
이 호출됨으로써 호출되는데 __bool__
이 구현되지 않았을 경우 기본적으로 True를 반환한다.
아래 링크에서 나머지 던더메서드의 종류를 확인할 수 있다.
https://docs.python.org/3/reference/datamodel.html
__len__
은 메서드가 아니라고 한다. 내장 자료형의 경우 성능 향상을 위해 C언어의 자료형 크기 필드 값을 그대로 반환하는 역할만 하는 매우 빠른 코드가 실행되기 때문이다. __abs__
도 마찬가지다. 파이썬은 순수성보다 실용성을 중요시하는 마인드기 때문에 이런 경우 특별하게 처리하는 것을 좋아하는 모양이다. 또한 파이썬은 특수 케이스는 전체 규칙을 허물을 정도로 특별하지 않다고 생각한다고 한다.