Python __delattr__ Method

Complete guide to Python's __delattr__ method covering attribute deletion, customization, and practical examples.

Python __delattr__ Method

Python delattr Method

Last modified April 8, 2025

This comprehensive guide explores Python’s delattr method, the special method invoked during attribute deletion. We’ll cover basic usage, attribute protection, descriptor interaction, and practical examples.

Basic Definitions

The delattr method is called when an attribute deletion is attempted on an object. It intercepts all del obj.attr operations. This allows customization of attribute deletion behavior.

Key characteristics: it receives the attribute name as string, must call super().delattr() for normal deletion, and can prevent deletion of specific attributes. It works with setattr and getattr for full attribute control.

Basic delattr Implementation

Here’s a simple implementation showing how delattr intercepts attribute deletion. The method is called whenever del is used on an instance attribute.

basic_delattr.py

class Person: def init(self, name, age): self.name = name self.age = age

def __delattr__(self, name):
    print(f"Deleting attribute: {name}")
    super().__delattr__(name)

p = Person(“Alice”, 30) del p.age # Triggers delattr print(hasattr(p, ‘age’)) # False

This example shows the basic interception of attribute deletion. The method prints a message before delegating to the parent class’s implementation for actual deletion. Without calling super, the attribute wouldn’t be deleted.

The super().delattr(name) call is crucial - it performs the actual attribute removal from the instance’s dict.

Preventing Attribute Deletion

delattr can protect certain attributes from being deleted by raising an AttributeError when deletion is attempted.

protected_attrs.py

class ProtectedData: def init(self, data, protected=False): self.data = data self.protected = protected

def __delattr__(self, name):
    if name == 'data' and self.protected:
        raise AttributeError("Cannot delete protected attribute 'data'")
    super().__delattr__(name)

pd = ProtectedData(“secret”, protected=True)

del pd.data # Raises AttributeError

del pd.protected # Works fine

This class prevents deletion of the data attribute when the protected flag is True. Attempting to delete it raises an AttributeError with a custom message.

This pattern is useful for creating classes with critical attributes that shouldn’t be accidentally deleted during program execution.

Logging Attribute Deletion

delattr can log attribute deletions for debugging or auditing purposes, tracking when and which attributes are removed.

logging_deletions.py

class LoggedDeletions: def init(self, **kwargs): for k, v in kwargs.items(): setattr(self, k, v)

def __delattr__(self, name):
    print(f"LOG: Deleting attribute '{name}' at {time.ctime()}")
    super().__delattr__(name)

import time obj = LoggedDeletions(x=10, y=20) del obj.x # Logs the deletion print(vars(obj)) # Shows remaining attributes

This implementation logs all attribute deletions with a timestamp. The actual deletion still occurs via the parent class’s implementation after logging.

Such logging can be valuable for debugging complex object lifecycles or monitoring sensitive data handling in applications.

Descriptor Interaction with delattr

When working with descriptors, delattr allows custom behavior when descriptor attributes are deleted, complementing delete.

descriptor_delattr.py

class Descriptor: def delete(self, instance): print(“Descriptor delete called”)

class MyClass: desc = Descriptor()

def __delattr__(self, name):
    print(f"MyClass __delattr__ for {name}")
    super().__delattr__(name)

obj = MyClass() del obj.desc # Calls both methods

This example shows the interaction between delattr and descriptor’s delete. Both methods are called when deleting a descriptor attribute, with delattr called first.

The order is: delattr intercepts the deletion, then the descriptor’s delete is called if present, and finally the actual attribute removal occurs.

Dynamic Attribute Cleanup

delattr can perform additional cleanup when attributes are deleted, such as closing files or releasing resources associated with them.

cleanup_delattr.py

class ResourceHolder: def init(self): self.file = open(’temp.txt’, ‘w’) self.cache = {}

def __delattr__(self, name):
    if name == 'file' and hasattr(self, 'file'):
        print("Closing file before deletion")
        getattr(self, 'file').close()
    super().__delattr__(name)

rh = ResourceHolder() del rh.file # Closes the file first

File is now properly closed before deletion

This class ensures proper cleanup when file attributes are deleted. The delattr method checks if the attribute being deleted is a file and closes it before proceeding with deletion.

This pattern helps prevent resource leaks when attributes holding resources are deleted from instances.

Best Practices

  • Always call super().delattr: Unless intentionally blocking deletion

  • Be careful with recursion: Avoid attribute access in delattr that might recurse

  • Document protected attributes: Clearly document which attributes cannot be deleted

  • Consider performance: Complex delattr logic can slow down attribute deletion

  • Use sparingly: Only implement when you need special deletion behavior

Source References

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Python tutorials.

ad ad