Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

파이썬에서 참조 전달과 값 전달 이해하기

파이썬에서는 모든 매개변수(인자)가 참조(reference)로 전달됩니다. 즉, 함수 내부에서 매개변수가 가리키는 대상을 변경하면 그 변경 사항이 함수를 호출한 쪽에도 그대로 반영됩니다.

다만 정확히 말하면 파이썬의 전달 방식은 '객체 참조에 의한 호출(call by object reference)'입니다. 변수 자체가 아니라 객체에 대한 참조가 전달되기 때문에, 리스트나 딕셔너리 같은 가변(mutable) 객체는 함수 안에서 수정하면 원본에도 영향을 미치지만, 숫자·문자열·튜플 같은 불변(immutable) 객체는 재할당해도 원본이 바뀌지 않습니다.

예제 1: 같은 객체를 수정하는 경우

#!/usr/bin/python3
# 함수 정의
def changeme(mylist):
    """전달받은 리스트를 변경하는 함수"""
    mylist.append([1, 2, 3, 4])
    print("함수 내부의 값: ", mylist)
    return

# changeme 함수 호출
mylist = [10, 20, 30]
changeme(mylist)
print("함수 외부의 값: ", mylist)

실행 결과

여기서는 전달된 객체의 참조를 그대로 유지한 채 같은 객체에 값을 추가하고 있습니다. 따라서 다음과 같은 결과가 출력됩니다.

함수 내부의 값: [10, 20, 30, [1, 2, 3, 4]]
함수 외부의 값: [10, 20, 30, [1, 2, 3, 4]]

append() 메서드는 새로운 객체를 만드는 것이 아니라 기존 객체를 직접 수정하기 때문에, 함수 밖의 원본 리스트에도 변경 사항이 그대로 반영됩니다.

예제 2: 참조를 덮어쓰는 경우

다음 예제는 인자가 참조로 전달되지만, 호출된 함수 내부에서 그 참조 자체를 다른 객체로 덮어쓰는 경우입니다.

#!/usr/bin/python3
# 함수 정의
def changeme(mylist):
    """전달받은 리스트를 변경하는 함수"""
    mylist = [1, 2, 3, 4]  # mylist에 새로운 참조를 할당
    print("함수 내부의 값: ", mylist)
    return

# changeme 함수 호출
mylist = [10, 20, 30]
changeme(mylist)
print("함수 외부의 값: ", mylist)

실행 결과

매개변수 mylist는 changeme 함수의 지역 변수입니다. 함수 내부에서 mylist에 새로운 리스트를 할당하면 전달받은 참조만 덮어쓰일 뿐, 함수 밖의 원본 객체에는 아무런 영향을 주지 못합니다. 결국 이 함수는 아무 작업도 수행하지 않으며, 실행 결과는 다음과 같습니다.

함수 내부의 값: [1, 2, 3, 4]
함수 외부의 값: [10, 20, 30]

정리

  • 파이썬은 인자를 참조로 전달하지만, 실제로는 '객체에 대한 참조'가 전달됩니다.
  • 함수 내에서 append() 등으로 객체를 직접 수정하면 원본 객체도 함께 변경됩니다.
  • 함수 내에서 매개변수에 새 객체를 할당하면 지역 참조만 바뀌고 원본은 그대로 유지됩니다.
  • 원본이 변경되지 않기를 원한다면 슬라이싱 복사본(mylist[:])을 전달하거나 copy 모듈을 활용하면 됩니다.