더북(TheBook)

또 한 가지 빠지기 쉬운 중요한 함정이 있다. 키가 없으면 setdefault에 전달된 디폴트 값이 별도로 복사되지 않고 딕셔너리에 직접 대입된다. 다음 코드는 값이 리스트인 경우 이런 동작으로 인해 벌어지는 상황을 보여준다.

data = {}
key = 'foo'
value = []
data.setdefault(key, value)
print('이전:', data)
value.append('hello')
print('이후:', data)

>>>
이전: {'foo': []}
이후: {'foo': ['hello']}

이는 키에 해당하는 디폴트 값을 setdefault에 전달할 때마다 그 값을 새로 만들어야 한다는 뜻이다. 즉, 호출할 때마다 리스트를 만들어야 하므로 성능이 크게 저하될 수 있다. 만약 가독성과 효율성을 향상시키고자 디폴트 값에 사용하는 객체를 재활용한다면 이상한 동작을 하게 되고 버그가 발생할 것이다(이런 유형의 다른 문제를 보고 싶다면 Better way 24: ‘None과 독스트링을 사용해 동적인 디폴트 인자를 지정하라’를 참고하라).

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.