My Python class defines __del__ but it is not called when I delete the object

The __del__ is a magic method in Python that serves as a destructor. Magic methods (also called Dunder methods) are identified by double underscores (__) as prefix and suffix.

In Python, we create an object using __new__() and initialize using __init__(). However, to destruct an object, we have __del__(). Sometimes __del__() may not be called when you expect it to be.

Basic Example

Let us create and delete an object ?

class Demo:
    def __init__(self):
        print("We are creating an object.")
    
    # destructor
    def __del__(self):
        print("We are deleting an object.")

# Creating and deleting an object
ob = Demo()
del ob
We are creating an object.
We are deleting an object.

Why __del__ May Not Be Called

However, there are several reasons why a class defines __del__ but it's not called when the object is deleted ?

Reference Count Issue

The del statement does not necessarily call __del__(). It simply decrements the object's reference count, and only if this reaches zero is __del__() called ?

class Demo:
    def __init__(self, name):
        self.name = name
        print(f"Creating {self.name}")
    
    def __del__(self):
        print(f"Deleting {self.name}")

# Multiple references to the same object
obj = Demo("Object1")
ref1 = obj  # Second reference
ref2 = obj  # Third reference

del obj      # __del__ not called yet (2 references remain)
del ref1     # __del__ not called yet (1 reference remains)  
del ref2     # Now __del__ is called (0 references)
Creating Object1
Deleting Object1

Circular References

If your data structures contain circular links, the reference counts will never go back to zero. Python's garbage collector may run sometime after the last reference vanishes ?

class Node:
    def __init__(self, name):
        self.name = name
        self.ref = None
        print(f"Creating {self.name}")
    
    def __del__(self):
        print(f"Deleting {self.name}")

# Creating circular reference
node1 = Node("Node1")
node2 = Node("Node2")
node1.ref = node2  # node1 references node2
node2.ref = node1  # node2 references node1 (circular!)

del node1
del node2
# __del__ may not be called immediately due to circular reference
print("End of program")
Creating Node1
Creating Node2
End of program

Solutions to Fix the Issue

Use Explicit Cleanup Methods

Do not rely on __del__() directly. Create a close() method that can be called multiple times safely ?

class FileHandler:
    def __init__(self, filename):
        self.filename = filename
        self.closed = False
        print(f"Opening {filename}")
    
    def close(self):
        if not self.closed:
            print(f"Closing {self.filename}")
            self.closed = True
    
    def __del__(self):
        self.close()  # Safe to call multiple times

# Proper usage
handler = FileHandler("data.txt")
handler.close()  # Explicit cleanup
del handler
Opening data.txt
Closing data.txt

Avoid Circular References

Use the weakref module to avoid cyclical references. It allows you to point to objects without incrementing their reference count ?

import weakref

class Node:
    def __init__(self, name):
        self.name = name
        self._ref = None  # Will hold weakref
        print(f"Creating {self.name}")
    
    def set_ref(self, other):
        self._ref = weakref.ref(other)  # Weak reference
    
    def get_ref(self):
        return self._ref() if self._ref else None
    
    def __del__(self):
        print(f"Deleting {self.name}")

# No circular reference issue
node1 = Node("Node1")
node2 = Node("Node2")
node1.set_ref(node2)  # Weak reference, no circular dependency

del node1
del node2
print("Cleanup complete")
Creating Node1
Creating Node2
Deleting Node1
Deleting Node2
Cleanup complete

Best Practices

Issue Solution Best Practice
Multiple references Explicit cleanup Use close() method
Circular references Weak references Use weakref module
Resource management Context managers Use with statement

Conclusion

__del__() may not be called immediately due to reference counting or circular references. Use explicit cleanup methods and weak references to ensure proper resource management. Consider context managers with with statements for automatic cleanup.

Updated on: 2026-03-26T21:47:34+05:30

3K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements