37
votes

From reading the docs, I understand exactly what getattr() and setattr() do. But it also says explicitly that getattr(x, 'foobar') is equivalent to x.foobar and setattr(x, 'foobar', 123) is equivalent to x.foobar = 123.

So why would I use them?

4
If you can't think of a good reason to use them, you probably don't have one. :) But one day, you've find yourself with an attribute name in a string variable (e.g., from user input, or computed by processing some JSON from a server, or whatever) and want to get the attribute with the name given in that variable, and that's when you'll use it. - abarnert

4 Answers

56
votes

Because you can use a dynamic variable too:

somevar = 'foo'
getattr(x, somevar)

You can't do that with regular attribute access syntax.

Note that getattr() also takes an optional default value, to be returned if the attribute is missing:

>>> x = object()
>>> getattr(x, 'foo')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'foo'
>>> getattr(x, 'foo', 42)
42

Using getattr() you can pull the attribute name from something else, not a literal:

for attrname in dir(x):
    print('x.{} = {!r}'.format(attrname, getattr(x, attrname))

or you can use setattr() to set dynamic attributes:

for i, value in enumerate(dynamic_values):
    setattr(i, 'attribute{}'.format(i), value)
9
votes

You use them if the attribute you want to access is a variable and not a literal string. They let you parameterize attribute access/setting.

There's no reason to do getattr(x, 'foobar'), but you might have a variable called attr that could be set to "foobar" or "otherAttr", and then do getattr(x, attr).

3
votes

Another case probably shows that they are not totally identical:

class A:
    def __init__(self):
        self.__var = 10
        setattr(self, '__var2', 100)

a = A()
print(a.__var2)
# 100
print(a.__var)
# AttributeError: 'A' object has no attribute '__var'

At least, setattr is not identical to ..

1
votes

I find it most useful when there is a possibility that the object whose attribute you need might be None. Exemplified below;

obj = None
attr_val = getattr(obj, 'anyvar', None) #This is not an error.