파이썬에서는 보통 Call by Object Reference, Call by Sharing이라고 한다
함수 호출 시 호출자의 변수 자체는 넘어가지 않는다. 호출자가 가리키고 있던 객체에 대한 참조(reference)가 넘어간다.
def func(x):Call by Value
a = 10
a ──> 10
func(a)
x ──> 10의 복사본
이때는 x를 변경해도 원래 a에는 영향을 주지 않는다.
Call by Reference
a ──> 값
↑
x
이때는 x를 다른 값으로 바꾸면 호출자의 a 또한 바뀌게 된다.
하지만 파이썬은 진짜 Call by Reference는 아니다
def func(x):
x = 20
a = 10
func(a)
print(a) # 출력은 10이 나오게 된다그렇다면 왜 20이 아닐까?
a ─────┐
↓
10
↑
x ─────┘
x = 20
a ──> 10
x ──> 20
이런 식으로 10 자체에 접근해서 20으로 수정하는 것이 아닌 x가 새로운 객체 20을 바라보게 만든다.
하지만 List에선
def func(x):
x.append(4)
a = [1, 2, 3]
func(a)
print(a) # [1, 2, 3, 4]a ─────┐
↓
[1, 2, 3]
↑
x ─────┘
x.append(4)
a ─────┐
↓
[1, 2, 3, 4]
↑
x ─────┘
이런 식으로 x를 다른 객체로 바꾸는 것이 아닌 x가 가리키는 리스트 객체 자체를 수정(mutation)한다.
재할당과 객체 수정을 구분하기
따라서 이 부분에서 중요한 것은 재할당(reassignment)과 객체 수정(mutation)을 구분하는 것이다.
정리
int, float, bool, str, tuple 등은 immutable 객체이고, list, dict, set은 mutable 객체이다.
시리즈에서 이어 읽기 · 파이썬 내부 파헤치기 →