Python 기초

참조값에 의한 인수 전달

함수를 호출할 때, 변수를 전달하는 경우가 많습니다. 혹시 이런 의문을 가져보았나요?

내가 전달하는 변수의 무엇이 함수로 전달될까요? 거의 모든 현대적인 프로그래밍 언어에서는 혼란을 막기 위하여 변수의 값만이 전달됩니다.

이것을 값에 의한 호출(call-by-value)라고 합니다. 값에 의한 전달(pass-by-value)도 동일한 의미입니다. 아래의 예제를 통해 의미를 확인해봅시다.

def modify(n):
	n += 1

k = 10
print("k =", k)

modify(k)
print("k =", k)

 

<실행 결과>

k = 10
k = 10

 

위의 코드에서 변수 k가 modify() 함수로 전달되었지만 k의 값은 호출 후에도 변경되지 않았습니다.

modify() 함수에서 매개변수 n의 값을 증가하였어도 말입니다. 이것이 바로 값에 의한 호출(call-by-value)입니다.

문자열을 전달하여도 마찬가지입니다.

def modify1(s):
	s += "To You"

msg = "Happy Birthday"
print("msg =", msg)

modify1(msg)
print("msg =", msg)

 

<실행 결과>

msg = Happy Birthday
msg = Happy Birthday

 

이것은 숫자나 문자열이 변경 불가능한 객체(immutable object)이기 때문입니다.

우리가 숫자나 문자열을 변경하게 되면 새로운 객체가 생성됩니다.

 

이것을 살펴보기 위하여 참조값을 출력하는 id() 함수를 사용하여 우리가 문자열을 변경하면 문자열의 참조값이 어떻게 되는지를 확인해봅시다.

msg = "Happy Birthday"
print(id(msg))

msg += "To You"
print(id(msg))

 

<실행 결과>

1491856947632
1491855917896

 

기존의 문자열의 끝에 "To You"를 추가했을 뿐인데 객체의 주소는 완전히 변경되었습니다.

리스트와 같은 변경 가능 객체(mutable object)를 전달하면 어떻게 될까요? 그렇다면 아주 다른 상황이 됩니다.

def modify2(li):
	li += [100, 200]

list = [1, 2, 3, 4, 5]
print(list)

modify2(list)
print(list)

 

<실행 결과>

[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 100, 200]

 

리스트는 변경 가능한 객체로서 modify2() 에 리스트를 전달한 후에 리스트의 내용을 변경하면 원본에 영향을 끼칩니다.

이것은 다음과 같이 알아 둡시다. 리스트의 경우에도 리스트의 참조값이 전달됩니다.

함수에서 참조값을 이용하여 리스트를 변경하면 리스트는 변경가능하기 때문에 새로운 객체를 생성하지 않고 기존의 객체가 변경됩니다.