Python

python mutable, immutable

Prower 2022. 7. 23. 03:20
728x90
반응형
  • python에서 모든 자료형은 객체로 저장한다.
  • a = 1 이라 함은 java나 c 처럼 1이라는 값이 들어가는게 아니라 1이라는 값을 가진 integer 객체가 들어가는 것

mutable

  • 실행 단계에서 객체 내부의 값을 수정할 수 있는 객체
  • list, set, dictionary 등이 mutable 객체에 속함
foo = [ 1,2 ]
print(id(foo))
foo.append(3)
print(id(foo))
​
>
4337981376
4337981376
  • 위 경우에서 foo라는 list에 하나의 아이템을 추가해면 객체 내부의 값이 변하지만, foo가 참조하는 객체는 동일하다

copy

foo = [ 1,2 ]
bar = foo
foo.append(3)
​
print(foo)
print(bar)
​
>
[1, 2, 3]
[1, 2, 3]
  • 일반적인 대입 연산자로 mutable 객체를 복사하면 해당 객체의 값이 복사되는게 아니라 객체의 reference가 복제된다.
  • 위 경우에서 bar에 foo를 대입하면, foo의 값인 [1,2] 가 복제되는게 아니라 foo가 가진 reference가 복제되는것
  • 따라서, foo에 3이라는 item을 추가하면 bar는 foo와 동일한 객체를 참조하므로 같은 값을 출력한다.
foo = [ 1,2 ]
bar = copy(foo)
​
print(id(foo))
print(id(bar))
​
>
4386061120
4386058944
  • mutable 객체의 값 자체를 복사하기 위해서는 내장함수 copy 를 사용하여 복제해야 하며, 값 내부에 또다른 mutable 객체가 있는 경우에는 deepcopy 를 사용한다.
foo = [ 1,2, [ 3,4,5 ] ]
bar = copy(foo)
​
print(id(foo[2]))
print(id(bar[2]))
​
bar = deepcopy(foo)
print(id(bar[2]))
​
>
4306467584
4306467584
4306617920
  • 위 경우에서 copy 를 사용하여 foo를 복사해도 mutable 객체인 [3,4,5]는 reference만 복사된다. 따라서 deepcopy를 통해 복제해야 값 자체가 복사가 됨

함수 호출

  • mutable 객체는 함수의 인자로 전달될 때도, 해당 값이 복사되어 전달되는게 아니라 reference가 전달된다.
foo = [ 1,2 ]
​
def foo_func(arg: list):
    arg.append(3)
​
foo_func(foo)
print(foo)
​
>
[1, 2, 3]
  • 위 경우에서 foo_func의 인자로 mutable 객체인 foo를 전달하면 함수의 인자 arg는 foo의 reference를 참조하게 되고, 3이라는 아이템을 동일한 객체에 추가하게 된다.

immutable

  • 객체 내부의 값을 수정할 수 없는 객체
  • int, str, float, tuple 등이 immutable 객체에 속함
foo = 1
print(id(foo))
foo = 2
print(id(foo))
​
>
4365588112
4365588144
  • 위 경우에서 foo에 새로운 값이 입력되는 경우 foo가 가진 값이 변하는게 아니라 아예 새로운 객체가 대입된다.

copy

  • immutable 객체는 대입 연산자로 값을 복사하는 경우 해당 객체의 값이 복사된 새로운 객체가 전달된다.
foo = 1
bar = foo
foo += 1
​
print(bar)
print(foo)
​
>
1
2
  • bar에 foo를 대입한 상황에서 foo의 값을 증가시켜도 bar에는 아무 영향이 없다.

함수 호출

  • 함수 호출 과정에서는 mutable 객체와는 다르게 reference가 아닌, 객체의 값이 복사된 새로운 객체가 생성되어 전달된다.
foo = 1
​
def foo_func(arg: int):
    arg += 1
​
foo_func(foo)
print(foo)
​
>
1
  • foo를 foo_func의 인자로 전달할 때 foo 객체 자체가 아닌 복사된 객체가 전달되고, 함수 내부에서 해당 객체에 추가적인 연산을 하더라도 원본 객체에는 영향을 미치지 못한다.
728x90
반응형