✔️ Python은 값이 아니라 “참조”를 전달한다!
즉, 함수에 변수를 넘기면 그 값 자체를 복사하는 게 아니라 그 변수가 가리키는 객체를 같이 바라보게 된다.
그럼 함수에 넘겨준 인자 값을 변경하면 다 바뀌나?
아니다!
이 차이는 객체 타입에 따라 다르다.
인자의 객체 타입이 가변(mutable)인 경우 함수 밖까지 영향을 미치고,
불변(immutable)인 경우 함수 밖에는 영향을 미치지 않는다.
불변 객체의 경우 list
, dict
, set
등이 해당하고,
가변 객체의 경우 int
, float
, str
, tuple
등이 해당한다.
만약 list를 함수에 인자로 넘겨주게 되었을 때 그 원본 값을 유지하고 싶다면,
함수 안에서 인자로 받은 값을 .copy()
를 통해 복사해 사용하면 된다!
“깊은 복사 deepcopy”를 안다면 위의 해결 방안이 맞나? 싶을 수 있다.
그렇다면 copy와 deepcopy의 차이점은 뭘까?
new_lst = lst.copy()
copy는 객체를 새로 생성해 그 안의 내부 객체는 원본을 참조하는 방식이다.
즉, 객체 자체는 새로 생성되었으나 내부는 그대로 원본과 공유하는 것이다.
이러한 방식을 얕은 복사 (shallow copy)라고 한다.
만약 1차원 list를 copy한 경우, 내부 객체가 int로 immutable이기 때문에 함수 내부에서 값이 변경되어도 원본이 유지된다.
다만 2차원 list를 copy했다면, 내부 객체 또한 1차원 객체로 mutable이어서 함수 내부에서 값 변경시 원본도 변경된다.
import copy
new_lst = copy.deepcopy(lst)
deepcopy는 객체를 새로 생성하고, 그 안의 내부 객체 또한 모두 새로 복사하는 방식이다.
deepcopy는 copy
를 임포트하여 사용할 수 있다.
위의 예시에서와 같이 2차원 list를 함수 인자로 넣으면서 원본을 유지하고자 하는 경우 사용할 수 있다.
유사하게 내부 객체가 list
, dict
등이 포함되어있다면 deepcopy를 사용하는 것이 안전하다.
단, 당연하게도 재귀적으로 복사가 이루어지기 때문에 copy보다 느리다.
copy | deepcopy | |
---|---|---|
외부 객체 | 새로 생성 | 새로 생성 |
내부 객체 | 원본의 내부 객체 참조 | 내부 객체 복사 |
사용 상황 | 내부 객체가 immutable인 경우 | 내부 객체가 mutable인 경우 |
속도 | 빠름 | 느림 |