객체 지향 프로그래밍/Python

변경 불가능한 자료형 주의하기

ghtis1798 2021. 3. 10. 14:06

변경 가능한 객체와 불가능한 객체

변경 불가능한 자료형

📌Immutable

변경 불가능한 객체는 무엇이 있을까?

파이썬에서는 대표적으로 문자열, 튜플이 있다.

str1 = 'Rainy day'
str1 = 'Sunny day'

str1에 저장한 문자열을 바꾸었다.

하지만 여기서 문자열을 수정한 것은 아니다.

서로 다른 객체로 바꿔치기 한 것이다.

문자열 객체는 총 두 번 생성되었기 때문이다.

'Rainy day'와 'Sunny day'

즉, immutable한 객체는 문자열이 변경되지 않고 새롭게 생성된다.

튜플도 마찬가지이다. 튜플은 값을 변경하려고 시도하면 에러가 발생한다.

📌Mutable

Mutable 객체는 변경 가능한 객체이다.

대표적으로 리스트, 딕셔너리가 있다.

list1 = [1,2,3,4,5]
list1[-1] = 100

이 경우 리스트의 인덱스에 직접 접근하여 값을 변경하는 것이 가능하다.

하지만 immutable 객체인 튜플을 위처럼 변경하려고 시도한다면 에러가 발생한다.

📌함수에 전달할 때?

파이썬에 대해 더 깊게 공부하며 특이하다고 느꼈던 부분이다.

파라미터로 전달할 때 그럼 어떤 복사가 일어날까?

처음 들었던 생각은 얕은 복사가 일어난다였다.

기본적으로 값의 복사가 얕은 복사로 이루어지기 때문이다.

id() 함수를 이용해서 주소값을 비교해본 결과 얕은 복사가 이루어졌다.

주의할 점은 immutable 객체를 대상으로 연산을 수행할 때 새로운 주소값에 값이 저장된다.

tuple_1 = (1,1)
tuple_2 = (1,2)
print(id(tuple_1)) # 2252023204416
def test(tuple_1, tuple_2):
    print(id(tuple_1)) # 2252023204416
    tuple_1 += tuple_2 
    print(id(tuple_1)) # 2252023774960
test(tuple_1, tuple_2)
print(tuple_1)
# 출력 결과는 (1,1)이다.

출력 결과는 (1,1)이다.

그 이유는 간단했다.

파라미터로 전달할 때는 tuple_1, tuple_2 모두 얕은 복사가 이루어졌다.

하지만 전달한 값이 tuple이고 tuple은 immutable 객체이다.

따라서 tuple_1 += tuple_2를 수행하는 순간 새로운 주소값에 결과가 저장된다.

결국 함수 밖에 있는 tuple_1의 값은 그대로인 것이다.

이를 반영해주려면 test 함수에서 마지막에 tuple_1 값을 return 해야 한다.

mutable객체는?

mutable 객체 역시 함수의 파라미터로 전달 시 얕은 복사가 이루어진다.

주소값이 전달되므로 함수 안에서 값을 변경할 경우 밖의 함수도 영향을 받는다.

list1 = [1,2,3]
list2 = [1,1,1]
def test(list1, list2):
    list1 += list2

test(list1, list2)
print(list1)
# 출력결과는?

아무 생각 없이 보면 list1의 결과는 [2,3,4]가 출력될 것이다.

하지만 파이썬에서 리스트 덧셈은 직접적인 덧셈을 수행하지 않는다.

따라서 결과는 [1,2,3,1,1,1]이 출력된다.

어쨋든 덧셈 결과가 list1에 변경되어 저장되었다.

따라서 mutable 객체도 함수 파라미터로 전달 시 얕은 복사가 이루어짐을 확인할 수 있다.