티스토리 뷰

Python

Call by object reference

Alledy 2019. 12. 1. 22:47

파이썬에서 함수에 인자를 전달하는 방식 - Call by object reference

함수에 인자를 전달할 때 사용하는 방식은 크게 2가지다.

  1. Call by value
  2. Call by reference

그런데 파이썬은, call by object reference란다. (…?)

 

Call by Value

def print_val(val):
    val += 10
    print(val)
    
i = 2
print_val(i) # 12
print(i) # 2

파이썬이기 때문에 Call by value라고 하면 안 되겠지만, 어쨌든 결과는 유사하므로 call by value라고 가정하자. Call by value는 i가 print_val의 인자로 넘겨졌을 때 i가 담고 있는 값인 2가 복사되어 val에 할당된 것이다. 그러므로 함수 밖에서 i는 여전히 2이다.

 

Call by reference

def print_ref(ref):
    ref[0] = 0
    print(ref)
    
i = [1,2]
print_ref(i) # [0,2]
print(i) # [0,2]

위의 call by value 예시와 다르게, print_ref 함수를 호출한 뒤에는 i값이 실제로 바뀐다. 함수에 인자를 넘길 때 값을 복사하는 것이 아니라, 해당 변수가 참조하고 있는 주소를 넘겼기 때문에 함수 내부에서 변경되면 외부에서도 마찬가지로 변경된다.

 

Call by object reference

파이썬에서는 모든 것이 객체인데 immutable한 객체와 mutable한 객체가 있다.

  • Immutable: int, float, tuple, str ..
  • Mutable: dic, list, set ...

변경 불가능한 값, 즉 이뮤터블 오브젝트가 인자로 전달되면 마치 call by value처럼 작동하고, 변경 가능한 값인 뮤터블 오브젝트가 전달되면 call by reference로 작동한다.

처럼이라는 말을 사용한 것은, call by value의 경우 겉으로 보기에는 비슷해보이는데 실제로는 조금 다르게 작동하기 때문이다. 파이썬에서는 C처럼 변수가 있는 메모리에 값을 저장하는 형태가 아니라, 값을 가리키는 형태이다. 변수와 값(파이썬에서는 모든 값이 객체이니 이하 객체라고 하자)은 다른 것이다.

x = 3 라고 했을 때 x는 변수이고 3 은 객체이다. 파이썬에서는 x라는 변수가 객체 3 를 저장하고 있는 것이 아니라, 객체를 가리킨다. 파이썬에서 모든 객체는 단 하나의 인스턴스를 갖고 있는 싱글톤 패턴이어서, 3 의 유일한 인스턴스를 x가 가리키고 있는 것이다. 이 때 y=x 라고 한다면, y라는 또다른 변수도 3 의 인스턴스(즉 x가 가리키고 있는 것과 똑같은)를 가리키게 된다.

파이썬에는 reference count라는 개념이 있어서, x와 y과 똑같은 객체를 가리킨다면, 해당 객체의 reference count는 2가 된다.

그러면 파이썬에서는 모든 것이 객체고, 3 같은 int 값도 객체이기 때문에 call by reference처럼 작동하는 것이 맞는 것 같다. 즉 아래 예시를 예로 들면 2라는 객체의 주소가 넘어가고, 그 객체가 변경됨으로써 i가 가리키는 객체의 value도 변경되어야 할 것 같다. 하지만 실제로는 call by value처럼 작동하여 함수 외부에서는 i가 가리키는 값은 그대로이다.

def print_val(val):
    val += 10
    print(val)
    
i = 2
print_val(i) # 12
print(i) # 2

이 이유는 print_val이 호출될 때 val이라는 변수가 생성되면서 i와 똑같은 객체, 즉 2의 인스턴스를 가리키게 되는 건 맞지만 여기에 +=10 이라는 연산이 들어갔을 때 객체 2의 인스턴스가 변동되어 12가 되는 것이 아니고, 새로운 객체 12의 인스턴스가 생성되며 val이라는 변수는 그것을 가리키게 되기 때문이다. 여전히 i는 객체 2의 인스턴스를 가리키고 있다. 그러므로 마치 call by value처럼, 이뮤터블 오브젝트는 인자로 전달되어도 함수 바깥에서는 변하지 않는다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함