Seul Lee

Mathpresso 서버 개발자

Navigation
 » Home
 » Github
 » XML Feed

Python 함수 인자 전달 방식, Call by object Reference

02 May 2018 » concept, python


함수 인자 전달 방식


프로그래밍 언어에서 일반적으로 사용하는 함수 인자 전달 방식은 2가지이다.

  1. Call by value, 값에 의한 호출
  2. Call by reference, 참조(주소)에 의한 호출



Call by value

Call by value는 말 그대로 값에 의한 호출, 즉 깂이 지정된 변수를 인자로 넘기는 것이 아니라 변수에 할당 된 값만을 복사해서 함수의 인자로 넘기는 방식이다.



# Call by value라고 가정



def a_print(value):
    print(value) 


a = 2  
a_print(a) 

(python이라 정확하게 말해 call by value가 아니지만, call by value라고 생각한다면)

a = 2라고 할당된 변수가 있고 이 변수를 함수의 파라메타로 넘겼을 때 a가 넘어간 것이 아니라 2라는 값이 메모리 상에 복사되어 value에 할당된다.

a_print라는 함수 내부에서 a의 값을 넘겨 받은 value의 값을 변경하더라도 a의 값은 변경 되지 않는다.

같은 2라는 값을 가졌더라도 a의 2와 value의 2는 실제 다른 위치의 메모리에 저장되어있기 때문이다.



Call by reference

Call by reference는 call by value와는 다르게 함수의 인자로 넘어간 값이 함수 내부에서 변경되되면 실제로 값이 변경된다.

Call by reference라는 이름에서 알 수 있듯이 참조를 호출하는 방식이다.

C언어에서는 포인터를 통해 구현이 가능한데 포인터는 주소 값을 가지고 있어 포인터를 함수의 인자로 넘기면 실제 메모리에 저장되어 있는 변수의 주소값을 넘기는 것과 같아 진다.

따라서 Call by reference로 인자를 넘기면 메모리 상에 저장된 실제 값에 변경을 줄 수 있기 때문에 함수 외부에서도 값이 변경되는 것을 볼 수 있다.



Python의 방식, Call by object reference

python은 위에서 설명한 일반적인 함수 인자 전달 방식과는 조금 다른 형태를 취한다.

python에서 모든 것은 객체(object)라는 말을 들어본 적이 있을 것이다.

1, 2 등의 숫자부터 시작해 모든 것이 객체이며 하나의 개체는 단 하나의 인스턴스로 존재한다(싱글톤).



a = 2  

python 언어의 특성으로 인해 아래와 같이 a = 2라고 변수를 할당하면 2라는 값이 a가 가르키는 메모리 공간에 할당되는 것이 아니라 2라는 인스턴스의 주소값을 a가 가르키게 된다.

즉, a = 2라고 하면 2라는 값이 a에 할당되는 것이 아니라 2라는 인스턴스를 a가 가르키게 되는 것이다.

다른 모든 경우에도 내부적으로는 위와 같이 동작한다. Python의 변수는 C언어 처럼 변수라는 메모리 공간에 값을 직접 지정하지 않는다.

a += 1을 할 경우 2라는 객체의 인스턴스가 3이되는 것이아니라 3이라는 객체의 인스턴스를 a가 가르키게 된다. 실제로 값이 변경되는 것이 아니라 가르키는 값이 변경되는 것이다.



추가로, python에서 객체들은 Reference Count라는 값을 가지고 있어, 자신을 가르키고 있는 변수의 숫자를 저장하고 있다.

다시 위의 예에서 a = 2일 때 2라는 인스턴스의 Reference count는 1이다 (시스템에서 참조하고 있어 실제로는 1 이상의 값)

하지만 a += 1이 실행되면 2라는 인스턴스의 Reference count는 0이 되고 3이라는 인스턴스의 Reference count는 1이 된다.


정리해 보자면 Python에서 모든 것은 객체이고 각 객체는 단 하나의 인스턴스를 갖는다.

변수는 메모리 공간에 값을 직접 지정하지 않으며, 해당 값의 인스턴스를 가르키고 해당 인스턴스의 Reference count를 증가시킨다.

연산 등을 통해 변수가 가지는 값이 변경되더라도 실제 메모리에 저장된 값이 변경되는 것이 아니라 가르키고 있는 인스턴스가 변경된다.