delattr()
`del` when the attribute name is a string — used for dynamic cleanup and namespace management.
Common call
delattr(obj, name)
Returns
None — the attribute is removed from the object
Replaces
`del object.name` when name is a runtime string
Watch out
raises AttributeError if missing; built-in types (str, int, list) reject with TypeError
delattr(objectobject — The object to modify. Instances of user classes accept delattr; built-in types like int, str, list reject it.type: Any · required, namename — The attribute name as a STRING. Raises AttributeError if the attribute does not exist on the object.type: str · required)
→ None
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| object | Any | yes | The object to modify. Instances of user classes accept delattr; built-in types like int, str, list reject it. |
| name | str | yes | The attribute name as a STRING. Raises AttributeError if the attribute does not exist on the object. |
Return value
None — Returns None. Deletes the attribute `name` from `object` — equivalent to `del object.name` when the name is known at runtime. Raises AttributeError if the attribute does not exist; raises TypeError when the target is an immutable built-in type.
Common patterns
Dynamic attribute cleanup
Remove attributes named at runtime — plugin cleanup, namespace scrubbing.
for attr in obsolete_names: if hasattr(obj, attr): delattr(obj, attr)
Guard for existence
delattr on a missing name raises — guard with hasattr or try/except.
if hasattr(obj, "cached_value"): delattr(obj, "cached_value")
Reset an instance to class defaults
Remove instance-level shadowing so class attributes show through.
class C: color = "red" c = C() c.color = "blue" # instance shadow delattr(c, "color") c.color # "red" (class attr again)
Prefer del for literal names
When the name is known at compile time, plain del is clearer.
del obj.name # clearer delattr(obj, "name") # only if "name" is a variable
Examples
1. Basic
class C: pass
c = C()
c.x = 1
delattr(c, "x")
hasattr(c, "x")
Returns
False2. Missing raises
delattr(obj, "missing")
Returns
AttributeError: 'C' object has no attribute 'missing'3. Built-in rejects
delattr(str, "upper")
Returns
TypeError: cannot delete 'upper' attribute of immutable type 'str'4. Removes shadow
class C:
x = "class"
c = C()
c.x = "instance"
delattr(c, "x")
c.x
Returns
"class" # class attr visible again5. Non-string name
delattr(obj, 42)
Returns
TypeError: attribute name must be string, not 'int'Pitfalls
1. Missing attribute raises AttributeError
Unlike `del d[key]` on a dict (which raises KeyError), delattr raises AttributeError for missing attributes. Different exception type — catch the right one.
Uncaught AttributeError
delattr(obj, "nonexistent")
AttributeError: 'C' object has no attribute 'nonexistent'
Guard with hasattr
if hasattr(obj, name): delattr(obj, name)
safe
2. Built-in immutable types REJECT delattr
Same restriction as setattr. You cannot delete attributes from str, int, list, ... — Python raises TypeError. Subclass if you need this level of control.
Built-in refused
delattr(str, "upper")
TypeError: cannot delete 'upper' attribute of immutable type 'str'
Not deletable — do not try
# built-in methods are permanent3. Deleting an instance attr may EXPOSE a class attr
If both the instance and the class have the same-named attribute, delattr(instance, name) removes the instance one, leaving the class one visible. Sometimes desired, sometimes surprising.
Expected gone
class C: x = "class" c = C() c.x = "instance" delattr(c, "x") c.x
"class" # not gone — class attr shows
Delete from class too
delattr(C, "x") # if you want it fully gone
AttributeError on access
4. __slots__ classes CANNOT delete slot attributes
A slotted attribute holds its slot — you can set the slot to None but delattr raises AttributeError.
Slot delete rejected
class P: __slots__ = ("x",) p = P() p.x = 1 delattr(p, "x")
AttributeError: 'P' object has no attribute 'x' # or similar
Set to sentinel
p.x = None
occupied but nullified
When to use
Use it
- Dynamic attribute deletion with a runtime name
- Cleaning up a namespace before serialization
- Removing instance-level shadows to expose class defaults
- Any place `del obj.name` is needed but `name` is a variable
Reach for something else
- You have a literal attribute name → use `del obj.name`
- The target is a built-in type → cannot be modified
- You want to overwrite → setattr with a new value
- You might be deleting a nonexistent attribute → guard with hasattr
Notes
Complexity
O(1) for a __dict__ deletion
Return
None
CPython impl
Python/bltinmodule.c :: builtin_delattr — calls PyObject_DelAttr
Memory
May free the slot in __dict__
Thread-safe
Depends on whether the underlying attribute access is safe
FAQ
Identical semantics — the operator form compiles to the same C call. Use `del` for literal names; use delattr when the name is a runtime string.
History
1.0
delattr() has been a builtin since Python 1.0.