기록하는삶

[파이썬/python] 함수의 parameter 전달 방식, call by object reference 본문

AI/파이썬(Python)

[파이썬/python] 함수의 parameter 전달 방식, call by object reference

mingchin 2022. 1. 18. 18:34
728x90
반응형

1) is와 ==

파이썬에서 변수를 할당(정의)한다는 것은 어떤 메모리 공간에 특정 내용을 저장하도록 하는 것이다. '=='은 그 내용끼리 같은지 확인하는 연산자이고, 'is'는 메모리 공간 자체가 같은 곳인지 확인하는 연산자(값만 비교하고자 할 때는 권장되지 않는다.)이다. 따라서 아래와 같은 차이를 확인할 수 있다.

 

?????

???????????

파이썬에서는 메모리 효율을 위해 빈번하게 사용되는 -5 ~ 256의 정수의 할당에 대해서는 같은 메모리 공간을 사용하도록 되어 있다고 한다. (고정된 메모리 공간의 사용)

위와 같이 서로 다른 두 변수 a,b를 정의하더라도 -5 ~ 256 범위에서 값이 같다면 같은 메모리 주소를 가리키고, 그 외(ex. 257)에는 그렇지 않다. 

 

무튼 is 연산을 통해 다른 이름으로 정의된 두 변수가 같은 메모리 공간을 가리키는지 확인할 수 있다.

 

2) 함수의 parameter 전달 방식

함수가 parameter를 전달받는 방식으로는 아래 세 가지가 있다.

 

① 값에 의한 호출(Call by Value)

 

변수의 값을 복제해 함수에 전달하는 방식으로, 파이썬에서 immutable한 변수들(수, tuple, dict의 key 등)은 마치 이 방식으로 전달되는 것으로 보일 수 있다.

값을 변경하면 메모리 주소가 변경되는 객체들. 혹은 값을 변경할 수 없는 tuple

 

② 참조에 의한 호출(Call by Reference)

 

JAVA 혹은 C언어의 포인터와 유사한 개념이라고 한다.(나는 모른다)

변수가 가리키는 메모리의 주소를 함수에 전달하는 방식으로, 함수 내부에서 변수를 조작한다면 외부에서도 그 결과가 반영된다. 파이썬에서 mutable한 변수들(list 등)은 마치 이 방식으로 전달되는 것으로 보일 수 있다.

 

값을 변경하면서 메모리 주소는 유지할 수 있는 객체들.

 

③ 객체 참조에 의한 호출(Call by Object Reference)

 

파이썬의 인자 전달 방식으로, 마치 ①과 ②가 적절히 섞여있는 것과 같다. 정확히는 객체 자체의 reference가 아니라 객체가 담고 있는 자료(data)의 reference를 전달하는 방식이다.

 

①의 예시. x 자리에 전달된 x는 분명 처음엔 a와 같은 곳(-100의 reference)을 가리키지만, 5를 더해 변화가 생긴 시점에 그 메모리 주소가 변경되며 다른 곳을 가리키게 된다. 즉 사용자 입장에서는 Call by Value는 아니지만 Call by Value인 것처럼 느껴진다. 그러나 2번째 예시에서 알 수 있듯 Call by Value가 아니라는 점!

하지만 list와 같은 mutable 객체를 다룰 때에는, 마치 ②처럼 작동하게 된다. list의 경우 그 메모리 주소를 바꾸지 않고도 값을 변경할 수 있기 때문에, 해당 위치에서 그 변수 값만을 바꾸게 되고 따라서 a와 x가 동시에 가리키는 [1,2,3]이라는 값을 변경함으로써 a 역시 변하게 된다. 이를 방지하기 위해서는 list copy를 적절히 사용해주어야 한다.

(list 관련 글: https://mingchin.tistory.com/84)

위처럼 함수에서 list를 전달받는 경우에는 list.copy()를 변수 할당 직후에 사용하는 습관을 들여야한다.

728x90
반응형