a = {}
class Test():
def __init__(self, name):
self.name = name
global a
a[self.name] = self
print(a)
def __del__(self):
print('삭제됩니다')
global a
print(a.pop(self.name))
b = Test('b')
del b
print(a)
의도한 것: del을 할 때 글로벌 리스트나 딕셔너리에서 자기 자신을 지워버리도록 소멸자를 제작
실제로 일어난 것: KeyError: 'b' 와 함께 전혀 딕셔너리 상에서 지워지지 않음
이게, 자신을 지우면서 딕셔너리에서 자신을 또 지우는 거 때문에 생기는 문제인가???
메모리가 뭔지도 모르면서 이런 거 짜려니 골이 깨지네
프붕아...
프붕아 소멸자는 refcount가 0일 때 호출된다
??? 근데 저 코드 실행시켜 보면 '삭제됩니다'까지는 잘 뜨던데???
프로그램 종료 되면서 뜨는거임
난 잘되는데 KeyError가 난다는 건 조금 이상한데 $ python del.py {'b': <__main__.Test object at 0x0000018384C20FD0>} {'b': <__main__.Test object at 0x0000018384C20FD0>} 삭제됩니다 <__main__.Test object at 0x0000018384C20FD0>
refcount가 a가 먼저 0이 될지 b가 먼저 0이 될지에 따라 다른거 같은데 매우 위험하다고 보여짐 소멸자 호출 순서는 확인은 안했지만 unspecified 일거로 추측함
인터프리터의 객체 해제 시점과는 별개로 애시당초 정상적인 프로그램이라면 실행 중엔 Test의 instance는 a가 key로 refcount 먹고 있으니 절대 소멸자가 호출될 수 없음
refcount를 증가시키지 않으면서 객체를 dictionary에 저장해야 하는 상황이라면 weakref 모듈을 찾아보셈. 나라면 공부 목적이 아닌 이상 개인적으로 애초에 저런 코드를 만들어야 할 상황인지 부터 점검 하고 싶음
혼자서 연구해봤는데, 다른 게 아니고 내가 저 셀을 여러 번 눌러가지고 b를 새롭게 정의할 때 소멸자가 호출되는 거고 제대로 하면 소멸 안 하는 거 확인했다;; ㄹㅇ 고마움
소멸자가 언제 호출되는지 관련해서 공부할 땐 쥬피터 등 interactive한 환경에서 하지 않고 아예 처음부터 실행시켜보는 게 좋음. 왜냐하면 IDE 등 환경이 해당 객체와 통신하기 위해 refcount를 잡아먹는 경우가 있음