최근 Python을 이용하여 알고리즘 문제를 자주 풀고 있으며 동시에 또 회사에서도 Python을 이용하여 백엔드 개발을 진행하고 있기에 Python에서는 어떤 방식으로 함수에서의 호출이 일어나는지 알아보고 싶어서 관련 내용을 정리하고자 한다.
우선 이에 대한 정리 전에 간단하게 Call by reference, Call by value가 무엇인지 알아보고자 한다.
1. Call by value
Call by value는 값에 의한 호출이다. 즉, 함수에 인자를 넘겨줄 때 인자에 "값"을 복사하여 넘겨준다는 것이다.
함수의 실행 환경을 저장하는 스택 프레임에 인자의 값의 복사본을 담음으로써 함수 내에서 스택 프레임 내에 존재하는 값을 사용할 수 있도록 한다.
그렇기 때문에 함수 내에서 만약 해당 인자를 변경하더라도 스택 프레임 내에 위치하고 있는 복사본을 변경하는 것이기 때문에 원본의 값은 변경되지 않는다.
예를 들어 신규 개발자를 선발하기 위해 면접을 진행하는 상황을 생각해 보자. 면접 때 담당자 2명이 경력기술서를 참고해야 하기에 원본을 한 부 더 복사한다. 이런 상황이 Call by value와 유사한 상황인 것이다.
HR 담당자에게 원본, 개발 실무자에게 복사본이 주어진 상황에서 개발 실무자가 복사본에 메모를 한다고 해도 HR 담당자가 가지고 있는 원본에는 어떠한 영향도 끼치지 않는다.
위와 마찬가지로 Call by value로 함수에 넘긴 인자에 함수 내에서 변경을 가하더라도 원본에는 어떠한 변경도 일어나지 않는 것이다.
2. Call by reference
Call by reference는 참조에 의한 호출이다. 즉, 함수에 인자를 넘겨줄 때 인자에 "참조"를 넘겨주는 것이다.
참조란 현재 메모리의 특정 주소를 차지하고 있는 변수 등에 부여한 새로운 별명(이름)이라고 생각하면 된다. 특정 메모리 공간에 부여한 새로운 별명이기 때문에 원래 이름과 동일한 것을 가리키게 된다.
그렇기 때문에 함수 내에서 외부로부터 넘겨받은 참조를 사용하여 인자의 내용을 변경한다면 당연히 원본도 변경되는 것이다.
Call by value보다 조금 이해가 어려울 수도 있을 것 같아 실생활에서 예시를 하나 들어보겠다. 필자의 출신 대학교에는 동땡이라는 동그란 모양의 의자와 가운데에는 식물이 있는 조형물?이라고 말할 수 있는 것들이 모여있는 장소가 있었다. 근데 오랜 시간이 흘러 올해 입학한 신입생들은 동땡을 금땡이라고 부른다고 해보자. 여기서 금땡이라는 새로운 별명이 Call by reference에서의 참조인 것이다.
학교 외부의 사람이 되어버린 필자의 친구들이 동땡이라고 부르던, 학교 내부 사람인 신입생들이 금땡이라고 부르건 이 둘은 모두 같은 장소를 의미한다. 동땡에 큰 나무를 심으면 당연히 금땡에서도 큰 나무를 확인할 수 있다. 동땡에 불이 났다면 금땡도 불이 난 것이다.
위와 마찬가지로 함수 외부의 원본과 함수 내부로 넘겨준 참조도 같은 메모리 상의 주소를 의미하는 것이다.
3. 그래서 Python에서는?
사실 Python의 경우에는 위의 두 경우 모두 해당하지 않는다! Python의 변수 전달 방식은 Call by assignment 또는 Call by object-reference이다. 이름에서 볼 수 있듯이 할당에 의한 호출이며, 인자에 할당되는 객체의 종류에 따라 참조 방식이 결정된다.
Python에서 객체는 두 가지 종류가 존재한다. list와 dict로 대표되는 가변(mutable) 객체와 int, string, tuple 등의 불변(immutable) 객체이다.
Call by assignment에서는 가변 객체는 Call by reference를 따르고, 불변 객체는 Call by value 방식을 따르게 된다.
정리하자면 Python에서는 할당되는 객체의 종류에 따라 참조 방식이 달라지는 Call by assignment를 따르며, 가변 객체는 Call by reference로, 불변 객체는 Call by value로 참조가 진행된다.
실제로 코드를 사용해서 확인해보면
Call by reference를 따르는 가변 객체는 함수 내에서 수정이 되면, 함수 밖의 원본도 수정된다.
Call by value를 따르는 불변 객체는 함수 내에서 수정이 되어도 함수 밖에서는 원본이 그대로 유지된다.
참고
'개발 > CS' 카테고리의 다른 글
트랜잭션이란? (1) | 2024.02.19 |
---|---|
(CS) 무중단 배포 (0) | 2024.01.08 |
(CS) 계수 정렬 & 기수 정렬 (1) | 2023.12.25 |
(CS) 트리 & 트라이 (0) | 2023.12.25 |
(CS) 객체와 객체지향이란? (0) | 2023.12.19 |