[python] del 명령어?
del?
1
2
3
4
5
x = 10
del x
print(x) # NameError 발생
Python에서 직접적으로 변수의 네임스페이스 참조를 제거하고,
참조 카운트를 감소시키는 명령어입니다.
어디에 쓰지?
엄밀히 말하면, 현대의 Python에서는 사실 쓸 이유가 별로 없습니다.
Python을 오래 써오신 분들도 del
이란 명령어의 존재 자체는 알지만
실제 개발에서 잘 사용하진 않습니다.
가비지 컬렉터(GC)가 알아서 다 해주기 때문입니다.
GC를 튜닝하거나 아예 끄지 않는 이상, 크게 필요가 없는 것이죠.
(GC를 끄고 개발할 수 있는 사람들은 그냥 C/C++을 쓰겠죠?)
복합 자료형에서 특정 객체를 삭제하는 데에 쓸 수도 있지만,
이미 여러 메서드가 이 역할도 수행하고 있습니다.
먼저 그나마 유용한 방법에 대해서
복합 자료형에서 특정 객체를 삭제
(사실상) 모든 것을 삭제
여기서 1번은 코딩 테스트에서 꽤나 유용하게 쓰이나, 2번은 잘못 쓰면 매우 위험한 존재입니다.
복합 자료형에서 특정 객체 삭제
리스트
1
2
3
4
5
arr = [10, 20, 30]
del arr[0]
print(arr) # [20, 30]
이렇게, 해당 객체에 직접 접근해서 네임 스페이스를 해제하여, 객체 자체를 삭제할 수 있습니다.
pop
처럼 값을 반환 받을 필요가 없고, 명시적으로 삭제를 행하고 싶다면 선택할법 합니다.
딕셔너리
딕셔너리의 경우, 특정 key
로 접근한 객체의 value
만 삭제하는 것이 아닌,
key-value
를 모두 삭제합니다.
1
2
3
4
5
d = {10:3, 20:6, 30:9}
del d[10]
print(d) # {20:6, 30:9}
복합 자료형 자체를 삭제
1
2
3
4
5
arr = [10, 20, 30]
del arr
print(arr) # NameError 발생
이렇게 객체 자체를 삭제하는 것이 가능합니다.
그리고 클래스, 변수, 함수 모든 것들이 1급 객체로 관리되는 파이썬에서는…
(사실상) 모든 것을 삭제
예… 클래스와 함수, 변수 모두 삭제할 수 있습니다.
삭제할 수 있는 항목은 다음과 같습니다.
- 클래스 자체
- 클래스 속성, 인스턴스 속성
- 클래스 메서드
- 전역 함수
- 기본 모듈 및 함수 (sum, print 등등…)
- 모든 변수
그러나 이러한 반컴퓨터적 파괴행위가 딱히 개발 인생에 쓸모는 없을 것 같습니다…
이제 조금 심화된 메모리와 관련된 내용으로 넘어가도록 합시다!
GC와 메모리 관리에 관한 내용입니다.
짧은 Python의 GC 설명
Python의 GC는 Java와는 조금 다르게 작동합니다.
객체의 참조 카운트를 확인하고, 0이 될 경우 메모리를 해제시킵니다. 순환 참조 탐지도 이루어집니다.
3개의 세대로 나누어, 각각의 주기에 따라 객체를 체크하고 메모리를 수집합니다. (Java와 유사합니다.)
del 문은 엄밀히 말하면 메모리를 해제하는 것이 아니라 앞서 말씀드렸듯
네임 스페이스를 제거하고, 참조 카운트를 0으로 만듭니다.
다만 참조 카운트가 0이 될 경우, GC가 꺼져 있어도 메모리가 해제되긴 합니다.
그러나 순환 참조 탐지가 이루어지지 않아 메모리 누수 위험이 있습니다.
GC를 튜닝하거나, 아예 끄는 경우
Python의 GC는 분명 많은 최적화가 이루어졌지만, 특정 상황에선 튜닝하는 게 훨씬 좋은 성능을 내곤 합니다.
이 때, 의도적으로 특정 변수를 삭제하여 매우 세밀한 메모리 조정에 사용할 수 있습니다.
대용량 파일을 여는 경우
일반적으로 대용량 csv 파일이나 이미지 파일, 문서 파일을 여는 경우 with 블럭을 사용합니다.
1
2
with open('대용량.csv', 'r') as f:
df = f.read()
이는 매우 강력히 권장되는 방법입니다.
with블럭을 쓰지 않을 경우, f라는 파일 자체에 대한 변수에 대해 .close()를 해주어야 합니다.
그렇지 않을 경우, 원본 파일의 데이터가 소실, 변형되는 치명적 문제를 야기할 수도 있습니다.
그렇다면, f
를 read()
하여 값을 담은 df
라는 변수는 with 블럭 밖에서 어떻게 될까요?
당연하지만 with 블럭 밖에서 여전히 값을 가지고 쓸 수 있는 변수입니다.
f
라는 변수에 할당된 파일의 원본 데이터만이 with블럭을 통해 제어되는 것입니다.
그런데 만약, df에서 값 몇 개만 가져오기만 할 거라면?
100mb가 넘는 csv 파일이라면?
1
del df
데이터를 모두 가져와서 변수에 할당했다면, df를 통해 메모리 상에서 데이터를 명시적
으로 삭제할 수 있습니다.
사실 알아서 GC가 메모리를 해제해주긴 합니다…
어디까지나 명시적인 코드를 위한 방안인 것이죠.