Python › Memory Management & Garbage Collection

Why is __del__ (the finalizer method) discouraged for critical cleanup logic, and what problems can it cause?

Advanced

Answer

__del__ is called when an object's refcount reaches zero, but its exact timing is not guaranteed -- especially with reference cycles, where objects in a cycle involving __del__ historically could never be collected (pre-3.4) or are now collected but in unpredictable order. __del__ can also resurrect objects by creating new references, complicate exception handling during interpreter shutdown, and generally should be replaced by explicit context managers or atexit handlers for reliable cleanup.
class Resource:
    def __del__(self):
        print('Cleaning up')  # timing not guaranteed, avoid relying on this

# Better: explicit context manager
class Resource:
    def __enter__(self): return self
    def __exit__(self, *a): print('Cleaning up')  # deterministic
Real-world example A codebase relying on __del__ to close database connections experiences intermittent connection leaks in production because objects involved in reference cycles get collected at unpredictable, delayed times.

Common follow-ups: How did Python 3.4's PEP 442 improve __del__ with cycles?;What's a safer alternative pattern for cleanup?