소멸자(Destructor)란 무엇인가?
파이썬에서 클래스는 __del__()이라는 특수 메서드를 구현할 수 있으며, 이 메서드를 소멸자(destructor)라고 부릅니다. 소멸자는 해당 클래스의 인스턴스가 곧 소멸(파괴)되기 직전에 자동으로 호출됩니다.
이 메서드의 주요 용도는 인스턴스가 사용 중이던 메모리 외부 리소스를 정리하는 것입니다. 예를 들어 열려 있는 파일 핸들, 데이터베이스 연결, 네트워크 소켓 등을 닫는 작업에 활용할 수 있습니다.
예제 코드
다음 예제의 __del__() 소멸자는 곧 소멸될 인스턴스의 클래스 이름을 출력합니다.
#!/usr/bin/python
class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __del__(self):
class_name = self.__class__.__name__
print class_name, "destroyed"
pt1 = Point()
pt2 = pt1
pt3 = pt1
print id(pt1), id(pt2), id(pt3) # 객체들의 id 출력
del pt1
del pt2
del pt3실행 결과
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.
3083401324 3083401324 3083401324 Point destroyed
동작 원리 살펴보기
출력 결과에서 주목할 점은 세 변수 pt1, pt2, pt3가 모두 동일한 id 값을 가진다는 것입니다. 즉, 이 세 변수는 같은 Point 객체를 참조하고 있습니다.
del 문은 객체 자체를 즉시 삭제하는 것이 아니라, 변수가 객체를 참조하는 참조(reference)만 제거합니다. 파이썬은 내부적으로 참조 카운팅(reference counting) 방식을 사용하므로, 마지막 참조가 제거되어 참조 카운트가 0이 되는 순간에 비로소 객체가 소멸되고 __del__() 소멸자가 한 번만 호출됩니다. 그래서 출력 결과에 "Point destroyed"가 딱 한 번 나타나는 것입니다.
알아두면 좋은 주의 사항
- 파이썬 3 문법: 위 예제는 파이썬 2 스타일의 print 문을 사용합니다. 파이썬 3에서는 print(class_name, "destroyed")처럼 함수 형태로 작성해야 합니다.
- 호출 시점 보장 없음: 순환 참조가 존재하거나 인터프리터 종료 시점에는 __del__()이 호출되지 않거나 실행 시점이 불확실할 수 있습니다. 따라서 반드시 정리해야 하는 리소스는 try/finally 구문이나 컨텍스트 관리자(with 문)를 사용하는 것이 더 안전합니다.
- 명시적 삭제: del 키워드는 참조를 제거할 뿐이며, 객체 소멸 시점은 파이썬의 가비지 컬렉터(garbage collector)가 결정합니다.