setattr()

Dot assignment when the attribute name is a string — useful for dynamic dispatch and configuration.

Built-in functionPython 1.0+Live demo
Common call
setattr(obj, name, value)
Returns
None — the attribute is set on the object
Replaces
the getattr with try/except pattern when writing rather than reading
Watch out
built-in types (str, int, list) are IMMUTABLE — assignment raises TypeError
setattr(objectobjectThe object to modify. Instances of user classes accept setattr; built-in types like int, str, list reject it.type: Any · required, namenameThe attribute name as a STRING. Not the identifier — a runtime value.type: str · required, valuevalueThe value to assign. Any type. Overwrites any existing attribute with the same name.type: Any · required)
None

Demo

Live evaluation
Try:
Inputs
typestrtype: str / list / user
attrstrattribute name
valuestrvalue to assign
Output
setattr('user', 'name', 'Alice')
'# user.name = Alice\nNone'

The demo picks a target — a user class or a built-in type — and tries to set an attribute. USER CLASSES accept setattr and store the value in the instance __dict__. BUILT-IN TYPES (str, int, list, ...) reject setattr with TypeError because they are immutable. This is the same distinction you would see writing `str.x = 1` in real Python.

Parameters

NameTypeRequiredDescription
objectAnyyesThe object to modify. Instances of user classes accept setattr; built-in types like int, str, list reject it.
namestryesThe attribute name as a STRING. Not the identifier — a runtime value.
valueAnyyesThe value to assign. Any type. Overwrites any existing attribute with the same name.

Return value

NoneReturns None. Sets the attribute `name` on `object` to `value` — equivalent to `object.name = value` when the name is known at runtime. Raises TypeError when the target is an immutable built-in type; raises AttributeError when the object cannot accept the attribute (e.g. __slots__ classes).

Common patterns

Dynamic attribute assignment
When the attribute name comes from data — config, user input, deserialization.
for key, value in config.items():
    setattr(obj, key, value)
Populate a namespace from a dict
Common in constructors that accept **kwargs.
def __init__(self, **kwargs):
    for k, v in kwargs.items():
        setattr(self, k, v)
Method injection (patching)
Add a method to an existing class at runtime.
def new_method(self):
    return 42
setattr(MyClass, "answer", new_method)
Prefer dot access for literal names
When the name is known at compile time, plain assignment is clearer.
obj.name = "Alice"          # clearer
setattr(obj, "name", "Alice") # only if "name" is a variable

Examples

1. Basic
class C: pass c = C() setattr(c, "x", 1) c.x
Returns
1
2. Overwrite existing
c.x = 1 setattr(c, "x", 99) c.x
Returns
99
3. Method injection
setattr(C, "greet", lambda self: "hi") C().greet()
Returns
"hi"
4. Built-in rejects
setattr(str, "foo", 1)
Returns
TypeError: cannot set 'foo' attribute of immutable type 'str'
5. Non-string name
setattr(obj, 42, "x")
Returns
TypeError: attribute name must be string, not 'int'
6. __slots__ rejects
class P: __slots__ = ("x",) p = P() setattr(p, "y", 1)
Returns
AttributeError: 'P' object has no attribute 'y'

Pitfalls

1. Built-in immutable types REJECT setattr
You cannot add attributes to str, int, list, dict, tuple, or any other built-in type. Attempting it raises TypeError with a clear message. Only user-defined classes (and their instances) accept setattr.
Built-in refused
setattr(str, "foo", 1)
TypeError: cannot set 'foo' attribute of immutable type 'str'
Subclass first
class MyStr(str): pass
setattr(MyStr, "foo", 1)
works
2. __slots__ classes only accept declared attributes
A __slots__ class has no __dict__ and rejects setattr for undeclared names. Attempts raise AttributeError, not TypeError.
__slots__ refused
class P:
    __slots__ = ("x",)
setattr(P(), "y", 1)
AttributeError: 'P' object has no attribute 'y'
Declare in slots
class P:
    __slots__ = ("x", "y")
setattr(P(), "y", 1)
works
3. Name must be a string
A common typo — passing a non-string as the attribute name. Python rejects it up front.
Non-string name
setattr(obj, 42, "x")
TypeError: attribute name must be string, not 'int'
Quote the name
setattr(obj, "42", "x")
works — sets attr "42"
4. Silently overwrites — no warning
setattr replaces existing attributes without any check. Combined with the dynamic-string form, this makes it easy to accidentally clobber. Guard with hasattr if you care.
Silent clobber
setattr(obj, name, new)   # even if obj.name already exists
old value gone
Guard first
if not hasattr(obj, name):
    setattr(obj, name, new)
explicit intent

When to use

Use it
  • Dynamic attribute assignment with a runtime name
  • Configuring an object from a dict or kwargs
  • Method injection (monkey-patching) — rare in modern code but occasionally useful
  • Any place `obj.name = value` is needed but `name` is a variable
Reach for something else
  • You have a literal attribute name → use dot access
  • The target is a built-in type → cannot be modified
  • You want deletion → delattr
  • You want to check first → hasattr + setattr, or just try/except

Notes

Complexity
O(1) for a __dict__ assignment; O(mro) if descriptors are involved
Return
None
CPython impl
Python/bltinmodule.c :: builtin_setattr — calls PyObject_SetAttr
Memory
May allocate slots in __dict__
Thread-safe
Depends on whether the underlying attribute access is safe

FAQ

Because built-in types (int, str, list, ...) are implemented in C and their layouts are fixed — no Python-level __dict__ exists. Attempting to add an attribute raises TypeError. Subclass the type if you need to attach attributes.

History

1.0
setattr() has been a builtin since Python 1.0.