파일 핸들이 이미 딕셔너리 안에 있으면 이 코드는 딕셔너리를 단 한 번만 읽는다. 파일 핸들이 없으면 get을 사용해 딕셔너리를 한 번 읽고, try/except 블록의 else 절에서 핸들을 딕셔너리에 대입한다(이런 접근 방법을 finally에 사용할 수도 있다. Better way 65: ‘try/except/else/finally의 각 블록을 잘 활용하라’ 참고). read 메서드를 호출하는 부분은 open을 호출하고 예외를 처리하는 코드와 잘 분리돼 있다.
이와 같은 로직을 구현하기 위해 in 식이나 KeyError를 사용한 접근 방법을 택할 수도 있지만, 오히려 딕셔너리를 더 많이 읽고 내포되는 블록 깊이가 더 깊어지는 단점이 있다. in이나 KeyError를 사용한 방법이 잘 동작한다는 사실을 알고 나면 setdefault를 활용한 방법도 잘 작동할 것이라 생각하기 쉽다.
try: handle = pictures.setdefault(path, open(path, 'a+b')) except OSError: print(f'경로를 열 수 없습니다: {path}') raise else: handle.seek(0) image_data = handle.read()