여러 프로그래밍 언어들에서 사용되는 함수 인수 전달방식에는 크게 3가지로 구분된다. 

  1. Call By Value
  2. Call By Reference
  3. Call By Object Reference

 

Call by Value

 함수에 인수를 전달하는 방식으로 변수의 값을 복사해 함수의 인자로 전달한다. 따라서, 함수 내에서 전달된 인자를 조작해도 함수 외부의 변수에는 영향을 미치지 않는다. C언어에서 이러한 함수인수전달 방식을 사용한다. 

 

Call by Reference

 함수에 인수를 전달하는 방식이다. JAVA언어나 C언어의 포인터로 함수의 인자에 전달하는 방식이 Call By Reference 같은 방식이다. 변수가 가리키는 주소값을 함수의 인자로 전달하게 된다. 그렇기에 함수 내에서 전달된 인자를 조작하면 함수 외부에 있는 원본 변수의 주소값에 있는 값을 바꿀 수 있다. 따라서, 함수 내에서 변경된 사항이 함수 외부에도 영향을 미치게 되는 것이다. 

 

Call by Object Reference

 파이썬은 Call by Value 같기도.. Call by Reference같기도 하다.. 결론부터 정의하자면 어떠한 데이터를 매개변수로 넘기는지에 따라 달라지는 것이라고 볼 수 있다. 

 파이썬은 모든 것이 객체이기 때문에 immutable(불변)한 자료형을 넘긴다면 Call by Value가 되는 것이고, mutable(가변)한 자료를 넘긴다면 Call by Reference가 되는 것이다. 그렇기 때문에 파이썬은 Passed by Assignment라고도 한다 ! 

 python에서 변수를 선언할 때, a="galaxy"라는 선언문이 있다고 생각해보자. 선언문이 실행되면 "galaxy"라는 문자열 객체가 생기고, 그 객체에 대하여 a라는 이름표를 붙이게 된다. 즉, python에서 변수는 위에서처럼 특정 메모리 공간을 할당받은 컨테이너 개념이 아니라, 어떤 객체에 붙여진 이름표일 뿐이다.

 물건에는 위치가 존재할 수 있다. 예를 들어 갤럭시워치을 남영역 31번 사물함에 숨겨뒀다면 "갤럭시워치"은 객체, "남영역 31번 사물함"은 갤럭시워치의 위치, 즉 주소 값이 된다. 그러나 갤럭시워치에 붙여진 이름표, 즉 변수에 대해서도 위치(주소값)를 지정해 두지는 않는다. "갤럭시워치"에는 여러 가지 이름표(변수)가 붙어있을 수도 있다. 예를 들어 해당 인형에 "호준이의 갤럭시워치", "복학생의 갤럭시워치"등의 여러 이름표가 붙어있다고 하자. 이때 변수"호준이의 갤럭시워치"의 주소 값(위치)과 변수"복학생의 갤럭시워치"의 주소 값(위치)은 객체 "갤럭시워치"의 주소 값(위치)으로 같다.

 다시 Call by object-reference이야기로 돌아가자면, python에서는 global인지 local인지 영역에 따라 변수들의 정보를 저장하는 namespace가 따로 있다. 즉, 전역 변수를 함수에서 인자로 받아오더라도 함수 내에서는 지역변수(이름표)에 불과하다. 함수 내에서 이름표를 떼서 다른 객체에 붙인다고 하더라도, 그 이름표는 함수 내에서만 사용하는 이름표일 뿐이다. 결국 함수 호출이 끝나면 전역 변수(이름표)가 여전히 그 객체에 붙어있다.

 예를 들어 list 1 = [1,2,3,4] 일 때, 함수 내에서 list 1을 [5,6,7,8]이라는 새로운 객체랑 binding 한다고 해도 함수 호출이 끝나면 list 1은 그대로 [1,2,3,4]이다.

 주의할 점은 이름표(변수)만 떼고 붙이는 것이 아니라, 이름표가 붙여진 물건(객체)의 구성품을 직접 조작하는 경우이다.  예를 들어 위의 예시와 같이 list 1 = [1,2,3,4] 일 때, 함수 내에서 list 1이라는 이름표가 붙여진 객체 [1,2,3,4]에 대하여  list 1 [0] = 5 이와 같이 객체 내의 요소(element)를 조작할 수 있다.

이 경우에 함수의 호출이 끝나서 지역 이름표가 전역 이름표로 바뀐다고 하더라도 객체가 변한 상태이므로 list 1은 [5,2,3,4]가 된다.

"복학생의 갤럭시워치" 이름표가 붙은 갤럭시워치의 끈을 초록색으로 염색했다면

"호준이의 갤럭시워치" 이름표가 붙은 갤럭시워치의 끈도 초록색인 게 당연하지 않겠는가?

(하나의 갤럭시워치에 두 개의 다른 이름표가 붙어있으므로)

 

 이때, 객체 자체를 바꾸려면 당연히 객체가 mutable, 즉 가변적인 포맷이어야 한다. 따라서 Call by object-reference 방식은 immutable 한 포맷의 객체(tuple 등)는 변경할 수 없지만, mutable한 포맷의 객체(list, dictionary, 직접 만든 클래스 등)는 변경할 수 있다는 특성을 갖는다.

'Python 프로그래밍' 카테고리의 다른 글

[Python] Coroutine  (0) 2022.06.02
[Python] Future  (0) 2022.06.01
[Python] mutable과 immutable  (0) 2022.05.26
[Programming] 암호화 알고리즘 (Encryption Algorithms)  (0) 2022.05.22
[Python(Web)] Robots.txt  (1) 2022.05.21

+ Recent posts