The delattr(object, name) function dynamically deletes a named attribute from an object at runtime using a string identifier.
Dynamic Cleanup & Reflection: Calling delattr(obj, "attr") is the programmatic equivalent of the statement del obj.attr. If the specified attribute exists on the target object, it is permanently removed; if it is missing, an AttributeError is raised. To inspect, access, or assign attributes dynamically, use companion built-in functions like hasattr(), getattr(), and setattr().
The delattr() function takes two arguments and returns None:
delattr(object, name)
| Parameter | Type | Role & Behavioral Details |
|---|---|---|
object |
Any mutable object | The target instance or class whose attribute will be deleted. |
name |
str |
The attribute name as a string identifier. Passing other types raises a TypeError. |
| Return Value | None |
Removes the attribute in-place and always returns None. |
Calling delattr() removes an attribute directly from the object's instance dictionary (__dict__):
class Animal:
species = "carnivores"
def __init__(self, name: str, age: int):
self.name = name
self.age = age
tiger = Animal("Ronald", 5)
print("Initial age:", tiger.age)
# Delete the age attribute dynamically
delattr(tiger, "age")
# Subsequent access raises AttributeError
try:
print(tiger.age)
except AttributeError as err:
print("AttributeError caught:", err)
Output:
Initial age: 5
AttributeError caught: 'Animal' object has no attribute 'age'
Deleting an attribute on one object leaves sibling instances untouched:
tiger = Animal("Ronald", 5)
lion = Animal("Alex", 6)
delattr(tiger, "age")
print("tiger has age:", hasattr(tiger, "age"))
print("lion age:", lion.age)
Output:
tiger has age: False
lion age: 6
del Statement vs. delattr() Function 🔝Both approaches trigger attribute deletion through __delattr__, but delattr() supports runtime variables:
| Feature | del obj.attr Statement |
delattr(obj, name) Function |
|---|---|---|
| Identifier Source | Hardcoded literal name in source code | Runtime string variable or dynamic input |
| Dynamic Field Names | Cannot use variables or strings | Accepts arbitrary runtime string expressions |
class Session:
def __init__(self):
self.token = "xyz123"
self.uid = 42
sess = Session()
# Static del operator
del sess.token
print("Token exists:", hasattr(sess, "token"))
# Dynamic delattr()
field = "uid"
delattr(sess, field)
print("uid exists:", hasattr(sess, "uid"))
Output:
Token exists: False
uid exists: False
Passing a class object to delattr() permanently removes the shared class attribute for all instances:
class Animal:
species = "carnivores"
tiger = Animal()
lion = Animal()
# Delete attribute on the class object itself
delattr(Animal, "species")
print("tiger has species:", hasattr(tiger, "species"))
print("lion has species:", hasattr(lion, "species"))
Output:
tiger has species: False
lion has species: False
Attributes created with hyphens or spaces via setattr() cannot be removed with del obj.attr-name due to syntax rules. delattr() removes them cleanly:
class HttpHeaders:
pass
hdr = HttpHeaders()
setattr(hdr, "content-type", "application/json")
setattr(hdr, "x-auth-token", "secret")
# Delete hyphenated attribute
delattr(hdr, "x-auth-token")
print("Headers after cleanup:", hdr.__dict__)
Output:
Headers after cleanup: {'content-type': 'application/json'}
__slots__ 🔝Python restricts attribute deletion on built-in types and slotted classes:
# 1. Built-in types reject attribute deletion
try:
delattr(42, "numerator")
except (AttributeError, TypeError) as err:
print("Built-in deletion error:", err)
# 2. Slotted classes permit deleting assigned slots
class Point:
__slots__ = ("x", "y")
pt = Point()
pt.x = 10
delattr(pt, "x")
print("pt has x:", hasattr(pt, "x"))
Output:
Built-in deletion error: 'int' object attribute 'numerator' is read-only
pt has x: False
Scrub sensitive fields dynamically before logging or transmitting user records:
def sanitize_user_profile(user_obj, sensitive_keys: list[str]):
for key in sensitive_keys:
if hasattr(user_obj, key):
delattr(user_obj, key)
class User:
def __init__(self):
self.username = "alice"
self.token = "secret_123"
self.ssn = "000-11-2222"
u = User()
sanitize_user_profile(u, ["token", "ssn"])
print("Sanitized fields:", u.__dict__)
Output:
Sanitized fields: {'username': 'alice'}
Purge cached calculations dynamically to force recomputation on subsequent reads:
class Report:
def __init__(self):
self.cached_total = 5000
def clear_cache(self, attr_name: str):
if hasattr(self, attr_name):
delattr(self, attr_name)
rep = Report()
rep.clear_cache("cached_total")
print("Cache cleared:", hasattr(rep, "cached_total"))
Output:
Cache cleared: False
__delattr__: If you override __delattr__ in your custom class and invoke delattr(self, name) inside it, Python enters infinite recursion! Always delegate to super().__delattr__(name).
class LoggedDeletion:
def __delattr__(self, name):
print(f"Auditing deletion of {name}")
super().__delattr__(name)
item = LoggedDeletion()
item.flag = True
delattr(item, "flag")
Output:
Auditing deletion of flag
Practice dynamic attribute deletion, PII scrubbing, and cache invalidation in our companion Jupyter Notebook:
Explore interactive code cells, implement dynamic PII sanitization pipelines, test __slots__ limits, and run self-validating assertions.
Run these unit checks directly in Python or your local environment to verify delattr() mechanics:
def test_delattr_mechanics():
class Product:
category = "hardware"
def __init__(self, sku: str):
self.sku = sku
p = Product("HW-001")
assert hasattr(p, "sku") is True
delattr(p, "sku")
assert hasattr(p, "sku") is False
try:
delattr(p, "sku")
assert False
except AttributeError:
pass
print("All delattr() unit assertions passed! 100% verified.")
test_delattr_mechanics()
Output:
All delattr() unit assertions passed! 100% verified.
Dynamically assigns or updates a named attribute on an object instance.
Retrieves the value of a named attribute from an object, with optional default fallback.
Checks whether an object possesses a specific attribute, returning True or False.
Returns the __dict__ mapping for an object or module namespace.
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.