본문 바로가기
파이썬/자주하는 질문

파이썬(Python) 함수 참조에 의한 호출?

by J-Build 2020. 9. 10.

C와 같은 언어에선 함수 호출 시 인자로 포인터를 넘겨서 참조(reference)를 가져올 수 있습니다.

 

이런 개념에 익숙하다면 파이썬에서의 함수 호출 시 인자가 '값에 의한 호출(call by value)'인지 '참조에 의한 호출(call by reference)'인지 헷갈릴 때가 많습니다. 

 

이럴 때는 딱 한가지만 기억하세요. 

파이썬은 '할당에 의한 전달(pass by assignment)' 이다.

 

먼저 함수를 사용하지 않는 아래 예제부터 먼저 볼께요. 변수값이 함수내에서 수정이 가능한지 확인하기 위해서 mutable 타입인 리스트(list)를 사용해 보겠습니다. 

a = [1, 2, 3] 	# 리스트(list) [1, 2, 3]을 a에 할당 했습니다. a는 리스트 [1, 2, 3]을 가리키게 되죠
b = a		# a를 b에 할당했습니다. b는 a를 가리키게 됩니다. 
print(b)	# b를 print()하면 a가 가리키는 리스트 [1, 2, 3]을 출력하게 되죠.
# [1, 2, 3] 

 

즉, 파이썬에서 할당이 되면 할당 된 변수(왼쪽: 변수 b)는 할당 한 변수(오른쪽: 변수 a)를 가리키게(pointing) 되는것이죠. 

그럼 할당 된 변수 b의 내용을 아래처럼 수정을 해볼께요. 

b[0] = 10	# 첫번째 아이템을 10으로 바꿔보고, (b가 가리키는 a의 첫번째 아이템이 10으로 바뀌게 되죠)
b.append(4)	# 리스트의 마지막에 4를 추가도 해보았어요. (b가 가리키는 a의 마지막에 4가 추가가 되죠)
print(b)	# 그리고 출력을 하면, b가 가리키는 a의 내용이 출력이 됩니다. 
# [10, 2, 3, 4]

print(a)	# 당연히, a의 내용이 수정되어 있겠죠. 
# [10, 2, 3, 4]

 

그럼 변수 b에 새로운 리스트를 할당하면 어떻게 될까요. b는 새로운 리스트를 가리키게 되어 a와의 연관은 끊어지게 됩니다. 

b = [6, 7, 8]	# 이제 b는 리스트 [6, 7, 8]을 가리키게 됩니다. 
print(b)	# b를 출력하면 b가 가리키는 [6, 7, 8]이 출력이 되게 되죠. 
# [6, 7, 8]

b.append(9)	# b가 가리키는 리스트에 9를 추가해보면
print(b)	# 당연히 그 리스트에는 9가 추가됩니다.
# [6, 7, 8, 9]

print(a)	# 하지만, a는 변한것이 없습니다. b는 새로운 리스트를 할당 받아서 더이상 a를 가리키지 않기 때문이죠.
# [10, 2, 3, 4]

 

이 개념은 함수를 호출 할 때에도 그대로 적용됩니다. 

즉, 아래와 같음 함수가 있다고 해볼께요. 

def add_item(content):
    modify.append(4)

 

이제 add_item() 함수에 리스트를 인자로 넣어서 호출해보겠습니다. 

c = [1, 2, 3]	# 변수 c에 리스트 [1, 2, 3]을 할당하면, c가 리스트 [1, 2, 3]을 가리키게 되죠.
add_item(c)	# 함수를 호출시, 함수의 파라미터인 content에 c가 할당이 되는것이죠. 
print(c)	# c를 출력을 해보면 4가 추가 되어있습니다.
# [1, 2, 3, 4]

 

add_item(c) 함수 호출시, 함수 파라미터인 content에 c가 할당이 되었습니다. 그리고 함수 안에서 content가 가리키는 c에 4를 추가(append)하게 되는것이죠. 결과적으로 인자로 넘긴 리스트에 값이 추가가 되어서 리스트의 내용이 변경이 되었습니다. 

 

만약 함수 내에서 파라미터인 content에 새로운 리스트를 할당하면 어떻게 될까요? 

def new_list(content):
    content = [5, 6, 7]	# 새로운 리스트 [5, 6, 7]을 content에 할당하는 순간 content가 가리키는 리스트는 [5, 6, 7]로 바뀌게 됩니다. 
    content.append(8)	# 즉, 새로운 아이템을 추가해도 content가 이전에 가리키던 리스트에는 추가가 안되는 것이죠. 

c = [1, 2, 3]
new_list(c)
print(c)	# c는 변한것이 없습니다. 왜냐하면 new_list()함수에서 새로운 리스트를 파라미터인 content에 할당했기 때문입니다. 
# [1, 2, 3]

 

네, c는 아무런 변화가 없게 됩니다. c와 파라미터인 content의 관계는 content에 새로운 리스트 [5, 6, 7]을 할당하는 순간 끊어졌기 때문입니다. 

 

변수에 리스트 할당시, 독립된 두개의 리스트를 만들고 싶다면 아래 포스팅을 확인해 주세요. 

2020/09/09 - [파이썬] - 파이썬 리스트 복사하기

 

파이썬 리스트 복사하기

파이썬(Python)으로 코딩할 때 가끔씩 리스트를 복사할 일이 생깁니다. 하지만 주의하지 않으면 오류를 만들어 디버깅을 힘들게 할 수 도 있습니다. 즉, 아래와 같이 새로운 리스트에 기존 리스트�

robotai.tistory.com

 

댓글