[Python] "Default argument value is mutable" 경고 발생 시 Develop Tip


파이썬 개발 시 종종,

위와 같이 키워드 패러미터로 넘기면서 디폴트 값이 빈 목록 [] 을 넘겨주면
"Default argument value is mutable..." 오류가 발생합니다.

이 이유가 무엇이고 어떻게 해결하는게 맞을 지 확인해 봅니다.

>>> def append(number, number_list=[]):
...     number_list.append(number)
...     return number_list
...
>>> append(5) # expecting: [5], actual: [5]
[5]
>>> append(7) # expecting: [7], actual: [5, 7]
[5, 7]
>>> append(2) # expecting: [2], actual: [5, 7, 2]
[5, 7, 2]

우선 위의 코드를 살펴보면, 
append 라는 함수를 호출하는데 특정 number 를 담고 있는 리스트를 결과를 받으려고 하는데
그 결과로 의도치 않게 계속 누적 목록을 받게 됩니다.

분명히 두번 째 number_list 패러미터는 안 주었기 때문에 빈 [] 목록에서 출발해야 하는데
결과는 그렇지 않습니다.

그 이유는 int, float, decimal, complex, bool, string, tuple, range, fronzenset, bytes 등과 같은
자료형은 immutable 객체이지만

list, dict, set, byte array, user-defined classes 등은 mutable 형으로써 위의 목록과 같이
수정된 것을 계속 반영하는 형식입니다.

결론은 키워드 패러미터의 디폴트 값으로 Mutable 자료형을 주지 말라는 것인데, 위의 것은
아래와 같이 같이 수정 가능합니다.


>>> def append2(number, number_list=None):
...     if number_list is None:
...         number_list = []
...     number_list.append(number)
...     return number_list
...
>>> append2(5)
[5]
>>> append2(7)
[7]
>>> append2(2)
[2]


이제 원하는 결과가 나왔습니다.

이런 현상을 막기 위해서 경고를 나타내었던 것이었군요.
아뭏든 어떤 경우든지 명확한 결과를 방해하는 것은
파이썬 세상에서는 되도록 막게 하는게 맞는 것 같습니다.

어느 분께는 도움이 되셨기를...

덧글

  • ash84 2017/04/27 17:59 # 삭제 답글

    잘 보고 갑니다. ^^ 신기해서 돌려봤습니다. 잘 배우고 갑니다.
  • 지훈현서아빠 2017/04/27 20:42 #

    도움이 되셨다니 저의 보람입니다~
  • 아일턴 2017/04/28 11:37 # 답글

    파이썬 관련한 포스팅 잘 보고있습니다. 매번 감사드립니다.
    질문이 하나 있습니다. 위 내용에서 디폴트값이 리스트로 들어갔을 때 수정 사항이 계속 누적되는 것을 보면,
    디폴트 인수는 함수가 선언될 때에 생성되고, 함수가 실행될 때에 디폴트 인수가 필요하게 되면 그 레퍼런스를 계속 가져다 쓴다고 이해할 수 있는 건가요?
  • 지훈현서아빠 2017/04/28 13:13 #

    네, 호출하는 곳에서 처음에 생기고 그것을 그대로 이용한다고 보는게 맞는 것 같습니다.
    관심 가져주셔서 고맙습니다. ^^
댓글 입력 영역

구글애드텍스트