파이썬의 가변 기본 인수로 인한 예상치 못한 동작 이해하기

2024. 11. 22. 14:04·Language/Python

파이썬은 강력하고 유연한 프로그래밍 언어이지만, 가끔은 예상치 못한 동작으로 개발자를 당황하게 만들기도 합니다. 그중 하나가 함수의 기본 인수로 가변 객체를 사용할 때 발생하는 문제입니다. 이번 글에서는 이러한 문제를 이해하고 해결하는 방법에 대해 알아보겠습니다.

문제 상황

다음과 같은 코드를 살펴보겠습니다.

def surprise(my_list = []):
    print(my_list)
    my_list.append('x')

surprise()
surprise()

많은 분들은 이 코드의 출력이 다음과 같을 것이라고 예상할 것입니다.

[]
[]

하지만 실제로 코드를 실행해 보면 다음과 같은 결과가 나옵니다.

[]
['x']

왜 이런 일이 발생할까요?

원인 분석

1. 기본 인수는 한 번만 평가됩니다.

파이썬에서 함수의 기본 인수는 함수가 정의될 때 한 번만 평가됩니다. 이는 함수가 호출될 때마다 기본 인수가 새로 생성되는 것이 아니라, 동일한 객체를 참조하게 된다는 의미입니다.

2. 가변 객체의 특성

리스트나 딕셔너리와 같은 가변 객체는 그 내용이 변경될 수 있습니다.
따라서 기본 인수로 가변 객체를 사용하고 이를 수정하면, 해당 객체는 함수 호출 간에 상태를 공유하게 됩니다.

3. 코드의 동작 과정

첫 번째 surprise() 호출:

  • my_list는 함수 정의 시 생성된 빈 리스트 []를 참조합니다.
  • print(my_list)는 []를 출력합니다.
  • my_list.append('x')를 통해 리스트에 'x'를 추가합니다.

두 번째 `surprise()` 호출:

  • my_list는 이미 'x'를 포함하고 있는 동일한 리스트를 참조합니다.
  • print(my_list)는 ['x']를 출력합니다.
  • my_list.append('x')를 통해 리스트는 ['x', 'x']가 됩니다.

이처럼 기본 인수로 사용된 리스트는 함수 호출 간에 상태를 유지하며, 이는 예상치 못한 결과를 초래합니다.

해결 방법

이 문제를 해결하려면 기본 인수로 가변 객체를 사용하지 않는 것이 좋습니다. 대신 기본 값을 `None`으로 설정하고, 함수 내부에서 새로운 객체를 생성하는 방법이 일반적입니다.

수정된 코드

def surprise(my_list=None):
    if my_list is None:
        my_list = []
    print(my_list)
    my_list.append('x')

surprise()
surprise()

수정된 코드의 출력

[]
[]

이제 각 함수 호출마다 my_list는 새로운 리스트를 참조하게 되어, 예상한 대로 동작합니다.

핵심 포인트

  • 가변 기본 인수 사용은 피해야 합니다. 함수의 기본 인수로 리스트나 딕셔너리와 같은 가변 객체를 사용하면 함수 호출 간에 상태가 공유됩니다.
  • 기본 값으로 None을 사용하세요. 기본 인수를 None으로 설정하고, 함수 내부에서 필요한 경우 새로운 객체를 생성합니다.
  • 기본 인수는 함수 정의 시점에 평가됩니다. 이는 함수 호출 시점이 아님을 명심해야 합니다.

추가 예시

이 개념을 더욱 이해하기 위해 다른 예시를 살펴보겠습니다.

def add_item(item, item_list=[]):
    item_list.append(item)
    return item_list

print(add_item(1))  # 출력: [1]
print(add_item(2))  # 출력: [1, 2]
print(add_item(3))  # 출력: [1, 2, 3]

위 코드에서`item_list`는 함수 호출 시마다 동일한 리스트를 참조하므로, 아이템이 계속 누적됩니다.

결론

파이썬에서 함수의 기본 인수로 가변 객체를 사용하는 것은 미묘한 버그를 유발할 수 있습니다. 이를 방지하기 위해서는 기본 인수로 None을 사용하고, 함수 내부에서 객체를 생성하는 패턴을 따르는 것이 좋습니다. 이러한 작은 습관이 큰 문제를 예방하고, 코드의 안정성과 가독성을 높이는 데 도움이 됩니다.

 

항상 기본 인수로 가변 객체를 사용할 때는 주의하시기 바랍니다!

저작자표시 비영리 동일조건 (새창열림)
'Language/Python' 카테고리의 다른 글
  • 파이썬으로 네이버 폼 매크로를 만들어보자
  • 파이썬으로 야구게임을 해보자
ssoaora
ssoaora
운영체제 공부 중
  • ssoaora
    Launcher
    ssoaora
  • 전체
    오늘
    어제
  • 블로그 메뉴

    • Home
    • About
    • Contact
    • Notice
    • Manage
    • 분류 전체보기 (12)
      • Language (3)
        • Python (3)
      • CS (1)
        • 컴퓨터 구조론 (0)
        • 운영체제 (1)
        • 네트워크 (0)
      • DB (0)
      • OS (1)
        • Windows (0)
        • macOS (0)
        • Linux (1)
      • Server (1)
        • NAS (1)
      • Design (0)
        • Illustrator (0)
      • 일상 (2)
      • 독후감 (0)
      • 칼럼 (2)
      • 리뷰 (1)
      • 자료 (1)
  • 인기 글

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
ssoaora
파이썬의 가변 기본 인수로 인한 예상치 못한 동작 이해하기
상단으로

티스토리툴바