<s>[INST] What is getattr() exactly and how do I use it? I was reading about the getattr() function. The problem is that I still can't grasp the idea of its usage. The only thing I understand about getattr() is that getattr(li, "pop") is the same as calling li.pop.
I didn't understand when the book mentioned how you use it to get a reference to a function without knowing its name until run-time. Maybe this is me being a noob in programming, in general. Could anyone shed some light to the subject? When and how do I use this exactly?
 [/INST] Objects in Python can have attributes (actually, every object has built-in attributes -- data attributes and methods (functions are values, i.e. objects, too) to work with those).
For example you have an object person, that has several attributes: name, gender, etc.
You access these attributes (be it methods or data objects) usually writing: person.name, person.gender, person.the_method(), etc.
But what if you don't know the attribute's name at the time you write the program? For example you have attribute's name stored in a variable called attr_name.
if
attr_name = 'gender'

then, instead of writing
gender = person.gender

you can write
gender = getattr(person, attr_name)

Some practice:
Python 3.4.0 (default, Apr 11 2014, 13:05:11)

>>> class Person():
...     name = 'Victor'
...     def say(self, what):
...         print(self.name, what)
... 
>>> getattr(Person, 'name')
'Victor'
>>> attr_name = 'name'
>>> person = Person()
>>> getattr(person, attr_name)
'Victor'
>>> getattr(person, 'say')('Hello')
Victor Hello

getattr will raise AttributeError if attribute with the given name does not exist in the object:
>>> getattr(person, 'age')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Person' object has no attribute 'age'

But you can pass a default value as the third argument, which will be returned if such attribute does not exist:
>>> getattr(person, 'age', 0)
0

You can use getattr along with dir to iterate over all attribute names and get their values:
>>> dir(1000)
['__abs__', '__add__', ..., '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']

>>> obj = 1000
>>> for attr_name in dir(obj):
...     attr_value = getattr(obj, attr_name)
...     print(attr_name, attr_value, callable(attr_value))
... 
__abs__ <method-wrapper '__abs__' of int object at 0x7f4e927c2f90> True
__add__ <method-wrapper '__add__' of int object at 0x7f4e927c2f90> True
...
__trunc__ <built-in method __trunc__ of int object at 0x7f4e927c2f90> True
__xor__ <method-wrapper '__xor__' of int object at 0x7f4e927c2f90> True
bit_length <built-in method bit_length of int object at 0x7f4e927c2f90> True
conjugate <built-in method conjugate of int object at 0x7f4e927c2f90> True
denominator 1 False
from_bytes <built-in method from_bytes of type object at 0x9ee4c0> True
imag 0 False
numerator 1000 False
real 1000 False
to_bytes <built-in method to_bytes of int object at 0x7f4e927c2f90> True

>>> getattr(1000, 'bit_length')()
10

A practical use for this would be to find all methods whose names start with test and call them.
 </s>