Website Logo
/ blog / python-getattr-is-bad

"getattr" is bad

Stop using getattr() so much.

The Zen of Python states as one of its axioms:

There should be one - and preferably only one - obvious way to do it.

Despite that, if you want to access the attribute of an object, there are two ways to do it:

human = Human()

# The normal way
human.brain

# and the getattr way
getattr(human, "brain")

Unless you truly have a good reason, you should always use the first way.

Why?

A couple other people have written about the different ways that using getattr has shot them in the foot. Their main points were:

I'd like to add my own experience to this list, and build on it:

I mean, take a look at this example:

def foo(obj: Human, methods: list[str]) -> None:
    for method in methods:
        getattr(obj, method)()

What methods are you calling on obj? You literally have no way of knowing without context about the whole application.

What's the fix?

Do this instead:

try:
    print(a.b)
except AttributeError:
    print("oh snap, 'b' doesn't exist!")

Why is this in the language in the first place?

Python is a dynamic programming language, and one of the reasons it's so powerful is because you can do some really cursed things with it. I want my programming language of choice to be strong and flexible enough to do anything. Does that mean I personally want to do those things? No - but I want the option available in case I do.

getattr is an "escape hatch" from sensible nice Python, just in case you need to do something whacky. Maybe to interface with a whacky library. Maybe there truely is a usecase that getattr and setattr lend themselves to.

Just because this escape hatch exists, it doesn't mean you should use it.

Using getattr is almost always a code smell. It's usually a sign that you're using dynamic trickery instead of solid, explicit design.