파이썬에서 기본 인자는 함수가 정의될 때 한 번만 계산되고, 매 호출 시마다 계산되지 않습니다. 이는 기본 인자의 값으로 변형 가능한 객체(예: 리스트나 딕셔너리)를 사용할 경우 모든 함수 호출에서 해당 인자가 명시되지 않으면 동일하게 공유된다는 의미입니다.
예:
def append_item(item, items=[]): items.append(item) return items print(append_item(1)) # [1] print(append_item(2)) # [1, 2], 기대했던 값은 [2]입니다.
올바른 방법:
def append_item(item, items=None): if items is None: items = [] items.append(item) return items
이제 각 호출은 자신의 리스트를 받게 됩니다.
질문: 기본값으로 변형 가능한 객체를 가진 함수를 여러 번 호출할 경우 어떤 일이 발생하나요?
답변: 매번 동일한 객체가 변경됩니다. 위의 예가 이를 설명합니다 — 리스트는 모든 값을 누적합니다.
이야기 대규모 웹 애플리케이션에서 데이터 캐싱을 위해 기본값으로 딕셔너리인 함수를 사용했습니다. 이는 서로 다른 사용자 간에 데이터가 "유출"되는 결과를 초래했습니다: 누군가 프로필을 변경하면, 이러한 변화가 때때로 다른 사용자에게도 나타나는 일이 생겼습니다. 이는 전역 딕셔너리의 공통 상태 때문입니다.
이야기 테스트에서 기본값으로 변형 가능한 리스트를 사용하여 통계를 수집했습니다. 한 테스트의 데이터가 다른 테스트로 "흘러들어"가 발생해, 예기치 않은 충돌, 버그 복제 불가능, 복잡한 디버깅을 초래했습니다.
이야기 로그 집계를 위한 마이크로서비스에서 기본값으로 리스트가 있는 함수를 사용하여 이벤트를 누적했습니다. 로그가 중복되었고, 오래된 요청의 일시적인 누적이 새로운 클라이언트에게 전달되어 조사와 데이터 손실에 몇 시간이 걸렸습니다.