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

파이썬 함수에서 인수를 값으로 전달하는 방법은 무엇일까?

파이썬 함수의 인수 전달 방식

파이썬에서 함수에 인수를 전달할 때는 객체 참조에 의한 호출(call by object reference) 방식이 사용됩니다. 다만 전달되는 객체가 불변(immutable)인지 가변(mutable)인지에 따라, 마치 값에 의한 전달(pass by value)처럼 보이는 경우가 있습니다.

다음 예제 코드를 살펴보겠습니다.

def modify(b, a):
    b = 30
    a = ['10']
    print("b =", b)
    print("a =", a)

b = 10
a = ['20']
modify(b, a)

이 코드를 실행하면 출력 결과는 다음과 같습니다.

b = 30
a = ['10']

함수 호출 후에도 원본 값은 그대로 유지됩니다

함수 내부에서 b와 a에 각각 새로운 값을 할당했지만, 함수 호출이 끝난 뒤 외부 변수를 확인해 보면 원래 값이 그대로 남아 있습니다. 함수 안에서의 재할당은 단순히 지역 변수가 새로운 객체를 가리키도록 만들 뿐, 호출자 쪽의 원본에는 아무런 영향을 주지 않기 때문입니다.

이러한 이유로 이 예제에서는 a가 마치 값으로 전달된 것처럼 동작합니다. 숫자(int), 문자열(str), 튜플(tuple) 같은 불변 객체는 함수 내부에서 직접 수정할 수 없으므로, 새로운 값을 대입하는 순간 새로운 객체가 생성되고 원본은 변하지 않습니다.

가변 객체는 참조처럼 동작합니다

반면 리스트(list), 딕셔너리(dict) 같은 가변 객체는 함수 내부에서 요소를 추가하거나 수정하면 원본 객체도 함께 변경됩니다.

def append_item(lst):
    lst.append('10')

a = ['20']
append_item(a)
print(a)  # ['20', '10'] - 원본이 변경됨

진짜 값으로 전달하고 싶다면 복사본을 넘기세요

가변 객체를 전달하면서도 원본이 변경되지 않기를 원한다면, 함수 호출 시 복사본을 전달하면 됩니다.

def append_item(lst):
    lst.append('10')

a = ['20']
append_item(a.copy())   # 또는 a[:]
print(a)  # ['20'] - 원본 유지

중첩된 구조까지 완전히 복사해야 한다면 copy 모듈의 deepcopy()를 사용하는 것이 안전합니다.

정리

파이썬은 항상 객체의 참조를 전달하지만, 불변 객체는 값에 의한 전달과 같은 결과를 보이고, 가변 객체는 참조에 의한 전달과 같은 결과를 보입니다. 값으로 전달되는 효과를 명확히 원한다면 copy()deepcopy()로 복사본을 넘기는 방법을 기억해 두면 좋습니다.