간단 설명)
함수의 parameter에 argument가 보내졌을때 처리하는 파이썬만의 독특한 방식입니다.
만약 함수에 mutable argument가 전달된다면
- 새로운 객체의 생성 없이 객체의 값이 변경됩니다. 그래서 함수가 만약 parameter의 값을 건든다면 argument의 값도 건들여지는거죠.
만약 함수에 immutable argument가 전달된다면
- 새로운 객체가 생성되서 parameter와 argument가 각각 참조하는 객체가 달라집니다. 그래서 함수가 parameter를 건들여도 argument는 그대로인겁니다.
Foo Function)
def foo(n):
n = n + 1
return n
x = 5
foo(x)
파이썬에서 foo function의 paramenter인 n으로 argument인 x를 보내는 상황입니다. (param과 arg가 각각 뭐를 나타내는지 주의해주세요)
x는 5였고 그 x가 foo function으로 보내져 1이 더해져 리턴되는 함수죠. 이때 n과 x는 다른걸까요? 값은 같을까요? 파이썬은 호출되는 argument의 type에 따라 다른 호출방식을 사용합니다. 바로...
Mutable vs. Immutable)
어떠한 객체가 mutable하다는 것은 그 객체를 참조하고 있는 변수의 값이 변동 되었을때 객체의 값이 변동되는 것을 의미합니다. 이게 무슨 당연한 소리지...? 코린이인 저로서는 당연하다는 생각이 드는 방법입니다.
예를 들어, [1, 2, 3, 4, 5]라는 리스트가 있습니다. 리스트는 mutable합니다. 만약 리스트의 정보를 업데이트한다고 하면 원래 존재하던 리스트 객체의 정보를 [1, 2, 3, 4, 5]에서 [1, 2, 3, 4, 6] 등으로 변경되는걸 의미 합니다. 새로운 생성 없이. 아주 자연스럽다고 생각합니다.
하지만 immutable한 객체는 조금 어색?합니다. 정수형은 immutable합니다.
잉???)
아니 위의 foo function에서 분명 정수형이였던 n이 5에서 6으로 바뀌지 않았나?
맞습니다. 밑의 그림을 봅시다.
foo(x)라는 함수가 실행됬을때 시점에선 a의 그림처럼 실행됩니다.
x, n 이라는 변수들이 전부 5의 값을 지니고 있는 정수형 객체를 참조하고 있죠.
그러나 문제는 foo func의 n = n + 1이라는 문장에서 발생합니다. b를 보시죠.
아까도 말했듯이 정수형 객체는 immutable합니다. 변경 불가능합니다. 아까 list처럼 단순하게 [1, 2, 3, 4, 6]으로 변경하는 것이 불가능합니다.
그래서 n은 아예 다른 객체를 참조하기로 합니다. 바로 5 + 1의 값을 지닌 새로운 객체를 새로 생성시켜 참조하는 것이죠.
단순히 5가 6으로 변경되는것이 아닙니다. 5라는 값을 가진 객체를 더이상 참조하지 않고,
6의 값을 가진 객체가 새로 생성되어 그 객체를 참조하게 되는 것입니다.
그 결과로 x는 원래 참조하고 있던 5의 객체를, n은 새로 생성된 6의 객체를 참조하게 됩니다.
이제 정리해봅시다)
그래서 x, n은 다르냐고요? 당연히 다릅니다. 값도 다르고 참조하는 객체도 다릅니다.
정리:
만약 객체가 mutable하다면,
- 새로운 객체의 생성 없이 객체의 값이 변경됩니다. 그래서 함수가 만약 parameter의 값을 건든다면 argument의 값도 건들여지는거죠.
- 이 호출 방식은 "Call by Reference"라고 불립니다.
- 저같은 코린이들이 주로 생각하는 방식입니다.
만약 객체가 immutable하다면,
- 새로운 객체가 생성되서 parameter와 argument가 참조하는 객체가 달라집니다. 그래서 함수가 parameter를 건들여도 argument는 그대로인겁니다.
- 이 호출 방식은 "Call by Value"라고 불립니다.
- foo func의 n의 값이 1이 더해져 6이 되어도 x는 여전히 5입니다.
그리고 이러한 파이썬만의 유연한?복잡한?머리 아픈? 호출 방식은 "Call by Object Reference"라고 불립니다.
설명에 질문이나 잘못된 부분 있다면 알려주시면 감사하겠습니다 :)
참고자료:
Do it! 자료구조와 함께 배우는 알고리즘 입문 : 파이썬 편
https://www.geeksforgeeks.org/is-python-call-by-reference-or-call-by-value/
'[Python]' 카테고리의 다른 글
[Python 공부] 리스트의 메소드 (0) | 2023.09.05 |
---|---|
[Python 공부] 리스트의 기초? (0) | 2023.08.29 |
[Python 공부] 탐욕의 알고리즘: Greedy Algorithm (0) | 2023.08.05 |
[Python 공부] Binary Search (0) | 2023.05.09 |
[Python 공부] Shallow Copy vs. Deep Copy (0) | 2023.05.08 |