DuckingRacoon
Python의 메모리 모델과 참조 본문
1. 변수는 객체에 대한 참조
파이썬에서 변수 = 값이 아니라, 변수 = 객체를 가리키는 참조입니다.
즉, 변수 자체가 데이터를 직접 저장하지 않고, 메모리 상의 객체를 가리킵니다.
a = [1, 2, 3]
b = a
b.append(4)
print(a) # [1, 2, 3, 4]
설명: b = a는 리스트를 복사한 것이 아니라, 같은 리스트 객체를 가리키는 참조를 하나 더 만든 것과 같습니다.
2. 얕은 복사(Shallow Copy) vs 깊은 복사(Deep Copy)
얕은 복사
객체 자체는 새로 만들지만, 객체 안의 참조 값은 그대로 공유.
import copy
original = [[1,2], [3,4]]
shallow = copy.copy(original)
shallow[0].append(9)
print(original) # [[1,2,9], [3,4]] ← 내부 리스트 공유
깊은 복사
객체와 내부 객체까지 모두 새로 생성.
deep = copy.deepcopy(original)
deep[0].append(8)
print(original) # [[1,2,9], [3,4]] ← 내부 리스트는 별도
3. 변경 가능 객체(Mutable) vs 변경 불가능 객체(Immutable)
Mutable: 리스트, 딕셔너리, 집합 등 → 내부 데이터를 바꿀 수 있음.
Immutable: 정수, 문자열, 튜플 등 → 내부 데이터 변경 불가.
x = (1,2,3) # 튜플(immutable)
# x[0] = 10 # TypeError 발생
4. 함수 호출 시 참조 전달
파이썬 함수는 객체 참조를 값으로 전달(pass-by-object-reference) 합니다.
즉, 함수 안에서 mutable 객체를 수정하면 원본이 바뀌지만, immutable 객체는 바뀌지 않음.
def append_item(lst):
lst.append(100)
my_list = [1,2,3]
append_item(my_list)
print(my_list) # [1,2,3,100]
5. 기본 인자로 mutable 객체를 두지 말아야 하는 이유
def func(data=[]):
data.append(1)
return data
print(func()) # [1]
print(func()) # [1, 1] ← 이전 호출의 리스트가 그대로 남아 있음
설명: 기본 인자는 함수 정의 시점에 한 번만 평가되므로, 같은 객체가 반복 사용됩니다.
안전하게 하려면:
def func(data=None):
if data is None:
data = []
data.append(1)
return data'Python' 카테고리의 다른 글
| enumerate() (0) | 2025.08.14 |
|---|---|
| all(...) (1) | 2025.08.14 |
| zip() (0) | 2025.08.14 |
| 언패킹 연산자 * (2) | 2025.08.14 |
| C++ 사용자 입장에서 알아야 할 Python 지식 (6) | 2025.08.14 |