setattr() is a built-in Python function that dynamically sets (or creates) an attribute on an object by name — the counterpart to getattr() and delattr(), enabling runtime attribute manipulation without hardcoding dot notation. In 2026, setattr() remains essential in data science (dynamic column assignment in pandas/Polars/Dask), software engineering (dependency injection, plugin systems, config-driven objects), and metaprogramming (dynamic class modification, proxy objects) — allowing flexible, introspective, and extensible code when attribute names come from variables, configs, or user input.
Here’s a complete, practical guide to using setattr() in Python: basic attribute setting, dynamic creation, real-world patterns (earthquake data enrichment, config injection, dynamic model attributes), and modern best practices with type hints, safety checks, performance, and integration with Dask/Polars/pandas/dataclasses/Pydantic.
Basic setattr(obj, name, value) — set or create attribute by string name.
class Earthquake:
def __init__(self):
self.mag = 7.2
self.place = "Japan"
eq = Earthquake()
print(eq.mag) # 7.2
setattr(eq, 'mag', 8.1) # update existing
print(eq.mag) # 8.1
setattr(eq, 'depth', 25.0) # create new
print(eq.depth) # 25.0
# Dynamic name from config
attr = 'country'
value = 'Japan'
setattr(eq, attr, value)
print(eq.country) # Japan
Real-world pattern: dynamic enrichment of earthquake DataFrame — add columns from config or calculation.
import pandas as pd
df = pd.read_csv('earthquakes.csv')
# Config-driven column creation
new_cols = {
'mag_rounded': df['mag'].round(1),
'is_major': df['mag'] >= 7.0,
'year': pd.to_datetime(df['time']).dt.year
}
for col_name, series in new_cols.items():
setattr(df, col_name, series) # adds as attribute (not recommended for df)
# Better: use df[col_name] = series (pandas way)
# But setattr works for custom objects
class QuakeReport:
def __init__(self, df):
self.df = df
def add_summary(self):
setattr(self, 'strong_count', len(self.df[self.df['mag'] >= 7.0]))
setattr(self, 'avg_mag', self.df['mag'].mean())
report = QuakeReport(df)
report.add_summary()
print(report.strong_count) # number of strong events
print(report.avg_mag) # average magnitude
Advanced usage — setattr with custom objects, modules, classes, and dynamic dispatch.
# Dynamic module attribute (rare, but possible)
import sys
setattr(sys, 'my_custom_var', 42)
print(sys.my_custom_var) # 42
# Dynamic class attribute
class Config:
pass
setattr(Config, 'THRESHOLD', 7.0)
print(Config.THRESHOLD) # 7.0
# Dynamic method addition (advanced, use with caution)
def strong_filter(self):
return self.df[self.df['mag'] >= 7.0]
setattr(QuakeReport, 'strong_filter', strong_filter)
report.strong_filter() # now callable
Best practices for setattr() in Python & data workflows. Prefer direct assignment obj.attr = value — when name is static; use setattr() for dynamic names. Modern tip: use Polars df.with_columns(...) — for dynamic columns; Dask ddf.assign(...). Use setattr() with hasattr() — check existence first if needed. Add type hints — def set_attr(obj: Any, name: str, value: Any) -> None: setattr(obj, name, value). Avoid setattr on built-ins — pollutes namespace. Use setattr() in factories — dynamic attribute population. Use setattr() in plugins — set hook methods. Use setattr() with operator.attrsetter — attrsetter('mag')(event, 7.5). Use setattr() in dataclasses — careful with frozen. Use setattr() in Pydantic — prefer model.__dict__[name] = value or model.model_dump(). Use setattr() in tests — mock attributes dynamically. Use setattr(obj, name, value) — for runtime config. Use setattr() with types.SimpleNamespace — dynamic objects. Use setattr() in decorators — attach metadata. Use setattr() with __slots__ — can still set dynamic attributes unless restricted. Use object.__setattr__(obj, name, value) — bypass overrides. Use setattr() in metaclasses — dynamic class attributes. Profile performance — setattr() is fast; avoid in ultra-tight loops. Use setattr() with vars(obj).update({...}) — batch set for __dict__ objects.
setattr(obj, name, value) dynamically sets or creates an attribute on an object by name — perfect for runtime configuration, plugin systems, and dynamic data objects. In 2026, use with hasattr() safety, prefer direct assignment when static, integrate with pandas/Polars/Dask for dynamic column setting, and use SimpleNamespace for simple dynamic objects. Master setattr(), and you’ll build flexible, runtime-adaptive code when attribute names are not known at write time.
Next time you need to set an attribute whose name you have as a string — use setattr(). It’s Python’s cleanest way to say: “Set this named attribute — even if I don’t know it statically.”