DEV Community

Adrienne Domingus
Adrienne Domingus

Posted on • Originally published at Medium on

Python: using getattr for properties and methods

Photo by Émile Perron on Unsplash

Using getattr

Before we jump into how getattr can be a useful tool for DRYing up our code, lets cover how it works (docs here)! In short, it takes an object and a string version of a property name, and returns the value of that property, if it exists on an object. It can optionally take a default value to return if the attribute can’t be found on the object, and otherwise will return an AttributeError.

Okay, let’s look at an example, using a bare-bones class. Given the Person class as defined below:

class Person(object):
    def __init__(self, first_name, last_name):
    self.first_name = first_name
    self.last_name = last_name

    def say_hello(name):
        print "Hello, {}!".format(name)
Enter fullscreen mode Exit fullscreen mode

Okay, let’s get an instance of a Person:

adrienne = Person("Adrienne", "Domingus")
Enter fullscreen mode Exit fullscreen mode

Once I’ve been instantiated, we can access my first_name (and last_name) attribute using the more familiar dot notation, but we can also get it using getattr, with the same result:

>>> adrienne.first_name
'Adrienne'
>>> getattr(adrienne, ‘first_name’)
‘Adrienne’
Enter fullscreen mode Exit fullscreen mode

This makes sense, because the _name attributes are…attributes. But now for the fun part: did you know that methods of a class are also attributes? For example:

>>> getattr(adrienne, 'say_hello')
<bound method Person.say_hello of <Person object at 0x10640de50>>
Enter fullscreen mode Exit fullscreen mode

Now, that doesn’t look very interesting, it didn’t actually do anything. But the power in this is that we can store that return value in a variable, and then call it. Like so:

>>> method = getattr(adrienne, 'say_hello')
>>> method("Someone else")
Hello, Someone else!
Enter fullscreen mode Exit fullscreen mode

Putting it to work: generalizing method calls

Okay, so it’s cool that you can use getattr to get methods as well as properties, but how does that help us? Well, this can definitely be useful in keeping your code DRY if you have some common logic surrounding branching method calls.

For example, if we need to make an API call, but which method we’re using depends on the context, instead of doing this:

if http_method == 'post':
    requests.post(url, data=data)
elif http_method == 'put':
    requests.put(url, data=data)
Enter fullscreen mode Exit fullscreen mode

We can do this:

method = getattr(requests, http_method)
method(url, data=data)
Enter fullscreen mode Exit fullscreen mode

The difference may seem a bit trivial in this example, but with objects that have significantly more method options than in this example, the initial method relying on if and elif statements scales particularly poorly. getattr to the rescue!

Top comments (0)