1

I would like to reliably call the __del__ method of an object immediately when it gets deleted. I am aware that this has been asked for python 2, but the documentation of python 3 claims that the __del__ method is called when the reference count reaches 0. However, this does not seem to be the case with my program

import time class MyClass: object_list = [] def __init__(self): MyClass.object_list.append(self) print("object initialized") def __del__(self): print("executing cleanup steps") MyClass.object_list.remove(self) a = MyClass() b = MyClass() c = MyClass() print(len(MyClass.object_list)) del b time.sleep(1) print("sleep finished") print(len(MyClass.object_list)) 

Try it online

What I want to achieve is to remove b from the object_list immediately when it is destroyed and also make the variable b inaccessible. So simply calling b.__del__() is not enough, I would need to also render b inaccessible.

Note: running first b.__del__() and then del b will lead to complaints when exiting the python interpreter.

Interestingly enough, a very similar program seems to call b.__del__() immediately when del b is executed.

import time class MyClass: counter = 0 def __init__(self, value): self.value = value print("object initialized") MyClass.counter+=1 def __del__(self): print("executing cleanup steps") MyClass.counter-=1 a = MyClass(5) b = MyClass(6) c = MyClass(7) print(MyClass.counter) del b time.sleep(1) print("sleep finished") print(MyClass.counter) 

Try it online

EDIT
@Pranav Hosangadi pointed out that there is still a reference to the object in the object_list. What a shameful oversight of mine. Now I came up with a workaround by calling first b.__del__() and then del b, but it is a two step process. I would like to have it in one step, if possible.

import time class MyClass: object_list = [] def __init__(self, value): self.value = value MyClass.object_list.append(self) print("object initialized") def __del__(self): print("executing cleanup steps") try: MyClass.object_list.remove(self) except: pass a = MyClass(1) b = MyClass(2) c = MyClass(3) print(len(MyClass.object_list)) b.__del__() del b time.sleep(1) print("sleep finished") print(len(MyClass.object_list)) 
1
  • 1
    "the documentation of python 3 claims that the __del__ method is called when the reference count reaches 0" MyClass.object_list still contains a reference to the object formerly known as b, so the b.__del__ isn't called. In the second case, there is no such reference, so b.__del__ is called immediately. Commented Dec 15, 2022 at 3:58

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.