'Better Way 18. __missing__을 사용해 키에 따라 다른 디폴트 값을 생성하는 방법을 알아두라' 정리
Series -
Contents
들어가며
Effective Python 2nd 파이썬 코딩의 기술 (교보문고 링크)을 제대로 이해하고자 블로그에 정리합니다.

현재 위치
Note
<2. Lists and Dictionaries>
Item 18: Know How to Construct Key-Dependent Default Values with
Better Way 18.
Item 18: Know How to Construct Key-Dependent Default Values with
__missing__Better Way 18.
__missing__을 사용해 키에 따라 다른 디폴트 값을 생성하는 방법을 알아두라한 줄 요약 및 첨언
키가 없는 상황을 처리하고자 할 때, defaultdict 으로도 해결이 안되는 상황이 올 수도 있습니다.
(defaultdict 은 키에 따라 다른 동작을 하게 할 수 없습니다.)
이 때, dict 을 확장하고 __missing__() 을 구현하면, key에 따라 다른 디폴트 값을 돌려 주게 할 수 있습니다.
사용 예시
def open_picture(profile_path):
try:
return open(profile_path, 'a+b')
except OSError:
print(f'경로를 열 수 없습니다: {profile_path}')
raise
class Pictures(dict):
def __missing__(self, key):
value = open_picture(key)
self[key] = value
return value
pictures = Pictures()
handle = pictures[path]
handle.seek(0)
image_data = handle.read()
기억해야 할 내용
책에서 챕터 마지막 부분에 적혀있는 내용입니다.
Tip
The
디폴트 값을 만드는 계산 비용이 높거나 만드는 과정에서 예외가 발생할 수 있는 상황에서는
setdefault method of dict is a bad fit when creating the default value has high computational cost or may raise exceptions.디폴트 값을 만드는 계산 비용이 높거나 만드는 과정에서 예외가 발생할 수 있는 상황에서는
dict의 setdefault 메서드를 사용하지 말라.Tip
The function passed to
defaultdict must not require any arguments, which makes it impossible to have the default value depend on the key being accessed.defaultdict에 전달되는 함수는 인자를 받지 않는다. 따라서 접근에 사용한 키 값에 맞는디폴트 값을 생성하는 것은 불가능하다.Tip
You can define your own
디폴트 키를 만들 때 어떤 키를 사용했는지 반드시 알아야 하는 상황이라면 직접 dict의 하위 클래스와
dict subclass with a __missing__ method in order to construct default values that must know which key was being accessed.디폴트 키를 만들 때 어떤 키를 사용했는지 반드시 알아야 하는 상황이라면 직접 dict의 하위 클래스와
__mising__ 메서드를 정의하면 된다.상세 설명
위 Visits 클래스의 add 에서 setdefault 를 사용한다면
class Visits:
def __init__(self):
self.data = {}
def add(self, country, city):
city_set = self.data.setdefault(country, set())
city_set.add(city)
setdefault라는 메서드 이름이 좀 애매해서 코드를 처음 읽는 사람이 동작을 바로 이애하기 어렵습니다.
그리고 setdefault() 부를 때, 키가 있더라도 set()이 항상 불리므로 효율적이라 할 수 없습니다.