파이썬에 대한 메모리 이모저모를 정리
1. 변수
temp = 'aa'
변수란 특정 메모리 주소를 담고 있는 것을 의미한다. 이것은 메모리 주소를 붙이는 라벨이라고 생각하면 된다
2. id 함수
id(obj)로 사용하며 해당 객체/변수의 메모리 주소 값을 반환한다
hex(id('a')) #'0x7f6bbabc76b0'
hex(id('b')) #'0x7f6bbabdc8f0'
a와 b는 서로 다른 메모리 주소 값을 반환하는 것을 알 수 있으며, C/C++ 의 & 포인터 연산자와 동일하다
# c/C++
char chr = 'a'
printf("%x", &chr)
# python
hex(id('a'))
3. is 와 ==
a is b : 메모리 주소를 비교하는 것이며, a == b : 두 개의 값만을 비교한다 것이다
a = 1000
b = 1000
a is b # False
a == b # True
------------------
a = 1000
b = a
a is b # True
a == b # True
== 에 비해 is가 약간 더 빠르며, is 연산자는 오버라이드가 불가능하다
4. mutable vs immutable
mutable
변경 가능한 객체
객체 값 변경 시 메모리 재할당 없음
ex ) set list dict
mutable1 = ['alpha']
print(hex(id(mutable1))) # 0x7f6b2b0f8880
mutable1.append('brabo')
print(hex(id(mutable1))) # 0x7f6b2b0f8880
리스트에 bravo에 대한 변수를 추가하더라도 메모리에 대한 주소가 변경되지 않는다
immutable
변경 불가능한 객체
객체 값 변경시 메모리 재할당
ex) int, float, string
immutable1 = 1000
print(hex(id(immutable1))) # 0x7f6b2b0b2130
immutable1 += 1
print(hex(id(immutable1))) # 0x7f6b2b0b2f90
주의점
a = 1000
b = a
b += 1
print(a, b, a is b) # 1000 1001 False
a = ['Mon', 'Tue']
b = a
b.append('wed')
print(a, b, a is b) # ['Mon', 'Tue', 'wed'] ['Mon', 'Tue', 'wed'] True
위에서는 mutable와 immutable에 대한 주의점은 메모리에 대한 할당 때문에 mutable의 a에도 'Wed'가 포함된다
그래서 이런것을 해결하기 위한 방법은 슬라이싱을 이용하거나 copy를 사용한다
a = ['Mon', 'Tue']
b = a[:] # only for list
b.append('wed')
print(a, b, a is b) # ['Mon', 'Tue'] ['Mon', 'Tue', 'wed'] False
a = ['Mon', 'Tue']
b = a.copy()
b.append('wed')
print(a, b, a is b) # ['Mon', 'Tue'] ['Mon', 'Tue', 'wed'] False
하지만 이중 리스트일 때는 copy가 얕은 복사를 하기 때문에 같은 다음과 같은 현상이 일어날 수 있다.
a = ['Head', ['Sub']]
b = a.copy()
b[1].append('Sub2')
print(a, b) # ['Head', ['Sub', 'Sub2']] ['Head', ['Sub', 'Sub2']]
copy.copy()는 해당 객체만 메모리를 새로 할당하며 하위 객체들은 메모리 주소 유지하게 된다.
[:]이나, .copy() 등과 같은 기능
이러한 얕은 복사는 파이썬에서는 copy.deepcopy()를 사용하여 해당 객체와 하위 객체들의 메모리를 새로 할당하는 방법이 있으며, 이것은 완전히 새로운 객체를 만드는 것이다.
import copy
a = ['Head', ['Sub']]
b = copy.deepcopy(a)
b[1].append('Sub2')
print(a, b) # ['Head', ['Sub']] ['Head', ['Sub', 'Sub2']]
'programming > python' 카테고리의 다른 글
[PY] line_profiler (@profile) (0) | 2023.03.04 |
---|---|
[PY] 캡슐화 (encapsulation) - @property (0) | 2022.11.27 |
[PY] 객체지향 - 상속 (inheritance) (0) | 2022.11.24 |
[PY] 파이썬의 global과 nonlocal (0) | 2022.11.23 |
[PY] 파이썬 진수 변환 (0) | 2022.11.22 |
댓글