안녕하세요. 휴먼스케이프의 개발자 김병하입니다.
파이썬의 스페셜메서드(special method)에 대해서 얘기해보려고 합니다.
스페셜 메서드(special method)란?
매직 메서드(magic method)라고도 부르는 스페셜 메서드(special method)는 파이썬 객체들이 동일하게 가지는 인터페이스라고 생각하셔도 좋을 것 같습니다.
파이썬에 있는 여러 내장 함수들이 호출하는 메서드를 사용자 정의 객체에 정의해서 내장함수를 사용할 수 있도록 하는 것이죠.
스페셜 메서드를 통해 사용자 정의 객체가, 반복, 컬렉션, 속성 접근, 연산자 오버로딩, 함수 및 메서드 호출, 객체 생성 및 제거, 문자열 표현 및 포맷, 블록 등 콘텍스트 관리 와 같은 기본적인 언어 구조체를 구현하고 지원하고 함께 사용할 수 있게 됩니다.
예를 들면, 객체 안에 __len__() 스페셜 메서드를 정의하면 파이썬 내장 함수인 len()을 사용할 수 있게 됩니다. 내장함수 len(obj)는 obj 안에 정의된 __len__() 메서드를 호출하죠.
앞 뒤에 언더바가 두 개가 들어가는 형식을 가져서 던더 메서드(dunder method)라고도 부릅니다.
스페셜 메서드(special method)의 예
표준 파이썬 시퀀스 스페셜 메서드
아래 코드는 special method 중 __init__(), __getitem__(), __len__()을 구현한 클래스입니다.
import collections Card = collections.namedtuple('Card', ['rank', 'suit']) class FrenchDeck: ranks = [str(n) for n in range(2, 11)] + list('JQKA') suits = 'spades diamonds clubs hearts'.split() def __init__(self): self._cards = [Card(rank, suit) for suit in self.suits for rank in self.ranks] def __len__(self): return len(self._cards) def __getitem__(self, position): return self._cards[position]
__getitem__() 와 __len__()을 구현하면, 사용자 정의 객체는 표준 파이썬 시퀀스처럼 작동하므로 아래와 같은 작업이 가능해진다.
deck[0] # 인덱스로 접근 가능하며
from random import choice choice(deck) # 랜덤선택을 해주는 choice 함수에 파라미터로 넘길 수 있으며
deck[:3] # 슬라이싱도 가능하고
for card in deck: # 반복문도 가능하고 print(card)
for card in reversed(deck): # 뒤에서 반복도 가능하고 print(card)
# 포함 여부를 확인할 수도 있음 Card('Q', 'hearts') in deck # __contain__() 이 정의되지 않은 경우
# 정렬도 가능하다 suit_values = dict(spades=3, hearts=2, diamonds=1, clubs=0) def spades_high(card): rank_value = FrenchDeck.ranks.index(card.rank) return rank_value * len(suit_values) + suit_values[card.suit]
for card in sorted(deck, key=spades_high): print(card)
수치형 스페셜 메서드
연산자 오버로딩과 비슷한 기능을 하도록 스페셜 메서드를 사용할 수 있습니다. 아래는 그 예입니다.
__add__() # + 연산자로 호출 __sub__() # - 연산자로 호출 __mul__() # * 연산자로 호출 __truediv__() # / 연산자로 호출
정리
스페셜 메서드를 적절히 사용하면 파이썬에서 제공하는 내장 메서드들을 효과적으로 사용할 수 있을 뿐 아니라, 파이썬스러운(pythonic) 아름다운 코드를 작성할 수 있습니다.
감사합니다.
이 포스트는 루시아누 하말류의 책 [Fluent Python]을 참고해서 작성했습니다.
Get to know us better! Join our official channels below.
Telegram(EN) : t.me/Humanscape KakaoTalk(KR) : open.kakao.com/o/gqbUQEM Website : humanscape.io Medium : medium.com/humanscape-ico Facebook : www.facebook.com/humanscape Twitter : twitter.com/Humanscape_io Reddit : https://www.reddit.com/r/Humanscape_official Bitcointalk announcement : https://bit.ly/2rVsP4T Email : support@humanscape.io