Python
getattr
Python functions
Python programming
Python tips

What is How to use getattr in Python?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

getattr() is Python’s built-in way to read an attribute when the attribute name is only known at runtime. It is simple on the surface, but it becomes especially useful in plugin systems, serializers, command dispatchers, and reflective utilities. Used carefully, it removes repetitive branching without making code harder to follow.

What getattr() Does

The basic signature is:

python
getattr(obj, name[, default])
  • 'obj is the object you want to inspect'
  • 'name is the attribute name as a string'
  • 'default is optional and is returned when the attribute does not exist'

Basic example:

python
1class User:
2    def __init__(self):
3        self.name = "Ada"
4        self.role = "admin"
5
6
7user = User()
8print(getattr(user, "name"))
9print(getattr(user, "role"))

This is equivalent to user.name and user.role, except the attribute name is dynamic.

Using a Default Value Safely

If the attribute might not exist, pass a default to avoid AttributeError.

python
1class Settings:
2    theme = "dark"
3
4
5cfg = Settings()
6print(getattr(cfg, "theme", "light"))
7print(getattr(cfg, "language", "en"))

Without a default, the second call would fail.

This is one of the most practical uses of getattr() in configuration-heavy code.

Dynamic Method Dispatch

getattr() is commonly used to call methods by name. This is useful in small command routers or plugin-style behavior.

python
1class Commands:
2    def greet(self):
3        return "hello"
4
5    def status(self):
6        return "ok"
7
8
9cmd = Commands()
10action = "greet"
11handler = getattr(cmd, action, None)
12
13if callable(handler):
14    print(handler())
15else:
16    print("unknown command")

This avoids long chains of if and elif when the mapping is simple.

getattr() Versus hasattr()

A common pattern is checking for existence before access, but many cases are simpler with one getattr() call and a default.

Less efficient pattern:

python
1if hasattr(user, "email"):
2    value = user.email
3else:
4    value = None

Clearer pattern:

python
value = getattr(user, "email", None)

This is shorter and avoids duplicate lookup logic.

Working With Nested Data Carefully

getattr() only handles one attribute at a time. If you need nested access, combine it carefully instead of building opaque one-liners.

python
1class Profile:
2    def __init__(self):
3        self.city = "Toronto"
4
5
6class User:
7    def __init__(self):
8        self.profile = Profile()
9
10
11user = User()
12profile = getattr(user, "profile", None)
13city = getattr(profile, "city", None) if profile is not None else None
14print(city)

For larger nested-access needs, a helper function may be justified, but keep error behavior explicit.

When getattr() Is a Bad Fit

Not every dynamic lookup is good design. If the set of possible attributes is fixed and known, direct attribute access is clearer. Overusing getattr() can hide mistakes and weaken static analysis.

For example, this is harder to read than necessary:

python
value = getattr(order, "total")

If total is always the intended field, order.total is better.

Use getattr() when names are genuinely dynamic, not just because it looks clever.

Interaction With Properties and Descriptors

getattr() does not bypass Python’s attribute model. It still triggers properties, descriptors, and __getattr__ / __getattribute__ hooks.

python
1class Product:
2    def __init__(self, price):
3        self._price = price
4
5    @property
6    def price(self):
7        print("property accessed")
8        return self._price
9
10
11p = Product(25)
12print(getattr(p, "price"))

That means getattr() can run side effects if the attribute is implemented with a property or custom descriptor.

Common Pitfalls

One mistake is forgetting the default value and assuming missing attributes will quietly return None. Another is using getattr() for fixed attribute names, which makes ordinary code less readable. Developers also sometimes call the return value as if it were always a method, even when it may be plain data. Finally, dynamic dispatch with unrestricted user input can expose private methods or unsafe behavior if names are not validated.

Summary

  • 'getattr() reads an attribute by name at runtime.'
  • Use the optional default to avoid unnecessary AttributeError handling.
  • It is useful for dynamic configuration, method dispatch, and reflective utilities.
  • Prefer direct attribute access when the name is known in advance.
  • Remember that getattr() still triggers properties and descriptor behavior.
  • Validate dynamic attribute names before using them in dispatch logic.

Course illustration
Course illustration

All Rights Reserved.