The getattr(object, name[, default]) function dynamically retrieves the value of an object's named attribute using a string identifier.
Safe Introspection: Calling getattr(obj, "attr") is the dynamic equivalent of static dot notation (obj.attr). If the requested attribute does not exist on the object, getattr() returns the specified default value instead of raising an AttributeError. To dynamically write, check, or delete attributes, use companion built-in functions like setattr(), hasattr(), and delattr().
The getattr() function accepts an object, an attribute name, and an optional default fallback:
getattr(object, name[, default])
| Parameter | Type | Role & Behavioral Details |
|---|---|---|
object |
Any object | The target instance, class, or module whose attribute is accessed. |
name |
str |
The name of the attribute as a string. Passing other types raises a TypeError. |
default |
Any object (optional) | The fallback returned if the attribute is missing. If omitted, an AttributeError is raised. |
| Return Value | Attribute value / default |
Returns the attribute value, or default when missing. |
You can read both instance attributes and shared class attributes using string names:
class Animal:
species = "carnivores" # Class attribute
def __init__(self, name: str, age: int):
self.name = name
self.age = age
tiger = Animal("Ronald", 5)
# Access instance and class attributes dynamically
print("Age:", getattr(tiger, "age"))
print("Species:", getattr(tiger, "species"))
print("Has age:", hasattr(tiger, "age"))
Output:
Age: 5
Species: carnivores
Has age: True
AttributeError with Default Fallbacks 🔝When an attribute does not exist on an object, direct dot notation raises an AttributeError. Supplying a third argument to getattr() gracefully returns a fallback value:
tiger = Animal("Ronald", 5)
# 1. Direct access raises AttributeError
try:
print(tiger.height)
except AttributeError as err:
print("Direct access error:", err)
# 2. getattr() with fallback default
height = getattr(tiger, "height", "No such attribute")
print("Safe getattr result:", height)
Output:
Direct access error: 'Animal' object has no attribute 'height'
Safe getattr result: No such attribute
Because Python functions and methods are first-class objects, getattr() can retrieve bound methods and invoke them dynamically at runtime:
class Calculator:
def add(self, a: int, b: int) -> int:
return a + b
def multiply(self, a: int, b: int) -> int:
return a * b
calc = Calculator()
operation = "multiply"
# Retrieve bound method and execute
func = getattr(calc, operation, None)
if callable(func):
print(f"Executed {operation}(6, 7):", func(6, 7))
Output:
Executed multiply(6, 7): 42
When attributes were populated dynamically via setattr() with names containing hyphens or spaces, dot notation fails. getattr() retrieves them cleanly:
class MetadataBag:
pass
meta = MetadataBag()
setattr(meta, "content-encoding", "gzip")
setattr(meta, "max-age", 3600)
print("Encoding:", getattr(meta, "content-encoding"))
print("Max-Age:", getattr(meta, "max-age"))
Output:
Encoding: gzip
Max-Age: 3600
To walk nested objects dynamically, chain lookups using functools.reduce():
import functools
class Engine:
hp = 450
class Car:
def __init__(self):
self.engine = Engine()
def get_nested(obj, path: str, default=None):
try:
return functools.reduce(getattr, path.split("."), obj)
except AttributeError:
return default
vehicle = Car()
print("Nested HP:", get_nested(vehicle, "engine.hp"))
print("Missing path:", get_nested(vehicle, "engine.turbo.psi", "N/A"))
Output:
Nested HP: 450
Missing path: N/A
Route commands to handler methods without complex conditional ladders:
class CommandHandler:
def handle_start(self, user: str) -> str:
return f"Service started for {user}"
def handle_stop(self, user: str) -> str:
return f"Service stopped for {user}"
def execute(self, action: str, user: str) -> str:
handler = getattr(self, f"handle_{action}", None)
if handler is None:
return f"Unknown action: {action}"
return handler(user)
dispatcher = CommandHandler()
print(dispatcher.execute("start", "alice"))
print(dispatcher.execute("reboot", "alice"))
Output:
Service started for alice
Unknown action: reboot
Extract fields from diverse model classes with fallback defaults:
def serialize_summary(record) -> dict:
return {
"id": getattr(record, "id", 0),
"title": getattr(record, "title", "Untitled"),
"status": getattr(record, "status", "draft"),
}
class Doc:
id = 101
title = "getattr Guide"
print(serialize_summary(Doc()))
Output:
{'id': 101, 'title': 'getattr Guide', 'status': 'draft'}
getattr(obj, "missing") with two arguments behaves identically to dot notation and raises an AttributeError. Always provide a default when uncertain.
@property that throws an AttributeError internally, getattr(obj, "prop", default) catches it and returns default, concealing bugs!
class BuggyProperty:
@property
def faulty(self):
raise AttributeError("Internal bug in property getter")
item = BuggyProperty()
val = getattr(item, "faulty", "fallback_value")
print("Masked fallback:", val)
Output:
Masked fallback: fallback_value
Practice dynamic retrieval, method dispatch, and property inspection in our companion Jupyter Notebook:
Explore interactive code cells, implement dynamic command dispatchers, test nested dotted paths, and run self-validating assertions.
View on GitHub Run in Google ColabRun these unit checks directly in Python or your local environment to verify getattr() mechanics:
def test_getattr_mechanics():
class Box:
color = "blue"
def __init__(self, weight: int):
self.weight = weight
b = Box(25)
assert getattr(b, "weight") == 25
assert getattr(b, "color") == "blue"
assert getattr(b, "height", 100) == 100
try:
getattr(b, "height")
assert False
except AttributeError:
pass
print("All getattr() unit assertions passed! 100% verified.")
test_getattr_mechanics()
Output:
All getattr() unit assertions passed! 100% verified.
Dynamically assigns or updates a named attribute on an object instance.
Checks whether an object possesses a specific attribute, returning True or False.
Deletes a named attribute directly from an object instance.
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.