본문 바로가기
Python

Passed-By-Assignment

by Deeppago 2022. 2. 18.

들어가기 앞서

Call by value(값에 의한 호출)는 인자로 받은 값을 복사하여 처리를 한다. Call by reference(참조에 의한 호출)는 인자로 받은 값의 주소를 참조하여 직접 값에 영향을 준다. 간단히 말해 값을 복사를 하여 처리를 하느냐, 아니면 직접 참조를 하느냐 차이인 것이다.

프로그래밍 구조상 Call by value(값에 의한 호출)를 하면 복사가 되기 때문에 메모리량이 늘어난다. 요즘에는 기기의 성능이 좋아져서 상관이 없다지만 많은 계산이 들어간다면 과부하의 원인이 된다. 하지만 복사처리가 되기 때문에 원래의 값은 영향을 받지 않아서 안전하다.

Call by value(값에 의한 호출)
장점 : 복사하여 처리하기 때문에 안전하다. 원래의 값이 보존이 된다.
단점 : 복사를 하기 때문에 메모리가 사용량이 늘어난다.

Call by reference(참조에 의한 호출)
장점 : 복사하지 않고 직접 참조를 하기에 빠르다.
단점 : 직접 참조를 하기에 원래 값이 영향을 받는다.(리스크)

 

1.  Python은 Call-by-value일까 Call-by-reference일까?

Python은 passed by assignment 방식을 따른다고 한다.

 

파이썬의 자료형엔 크게 immutable(불변)과 mutable(가변)으로 나뉜다. 각각의 종류는 아래와 같다.

immutable(불변)

  • integer
  • string
  • tuple

mutable(가변)

  • list
  • dictionary

Python에서는 불변 타입의 객체를 넘기면 call by value 가 되고 가변 타입의 객체를 넘기면 call by reference 가 된다. 즉 할당 되는 것에 따라 전달 방식이 달라지는 것이다.

 

왜 이렇게 동작하는 것일까?

Python에선 모든 것이 객체이기 때문이다.

 

mutable 객체는 새로 메모리에 할당하지 않고 레퍼런스만 유지 되서 call-by-reference 처럼 작동한다.

아래 코드를 보자

>>> a = [1,2,3,4]
>>> b = a
>>> b.append(5)
>>> print(a)
[1,2,3,4,5]
>>> print(b)
[1,2,3,4,5]

 

a 배열은 [1, 2, 3, 4] 4개의 원소를 가지고 있고, b가 a 배열을 참조하고 있다. 이때 b 배열에 5라는 원소를 추가하면 어떻게 될까?

a를 출력하였을때 5가 추가된것을 확인할 수 있다. 이는 mutable한 객체 list를 call-by-reference로 참조하였기 때문이다. a와 b는 메모리 상에서 동일한 주소를 가리키고 있는것이다.

 

하지만 immutable 객체는 다르게 작동한다.  int 타입의 변수(객체) 를 함수의 인자 값으로 넘기면 이 객체는 불변 이기 때문에 함수 안에서는 새로운 값을 생성한다.

이는 마치 call-by-value 처럼 보이게 한다. 호출할 때 쓰인 변수 A와 함수 내의 A'는 서로 다른 값을 가지게 된다.

이해를 위해 아래 예제로 확인해보자.

>>> a = 5
>>> b = a
>>> b += 1
>>> print(a)
5
>>> print(b)
6

 

배열과 달리 정수형 변수(객체)는 a의 값이 변하지 않았다. 이는 call by value방식으로 b가 a를 참조하여 새로 메모리에 할당 되었기 때문이다. 그렇기에 파이썬은 passed by assignment 라고 한다.

 


참고 자료

https://codingplus.tistory.com/29

https://www.pymoon.com/entry/Python

https://ledgku.tistory.com/54

 

'Python' 카테고리의 다른 글

Duck Typing  (0) 2022.02.17
property (함수/데코레이터)[파이썬/python]  (0) 2022.02.17
메모리 누수[파이썬/python]  (0) 2022.02.17
GC(Garbage Collection)  (0) 2022.02.16
GIL(Global Interpreter Lock)  (0) 2022.02.16

댓글