I stumbled across this behaviour, which suggests that you can use getattr to call methods on a class instance, as an alternative to the intuitively named operator.methodcaller:
from operator import methodcaller
class Foo():
    def __init__(self, lst):
        self.lst = lst
    def summer(self):
        return sum(self.lst)
my_obj = Foo(range(11))
res1 = methodcaller('summer')(my_obj)  # 55
res2 = getattr(my_obj, 'summer')()     # 55
assert res1 == res2
I'd like to understand, internally, why this works. Is it because all methods are also attributes? This seems to be the case because dir(Foo) or dir(my_obj) includes 'summer'. But I have never heard methods referred to as attributes of a class or class instance, e.g. this isn't mentioned in What is a “method” in Python?
There is an explanation in the docs which mentions differentiation between "data attributes" and "non-data attributes" which I failed to understand.
Update: Comments by @Amadan have clarified most of the above. The only remaining bit I do not understand is this excerpt from the docs:
If you still don’t understand how methods work, a look at the implementation can perhaps clarify matters. When a non-data attribute of an instance is referenced, the instance’s class is searched. If the name denotes a valid class attribute that is a function object, a method object is created by packing (pointers to) the instance object and the function object just found together in an abstract object: this is the method object.
So is a non-data attribute determined by checking whether it is callable, or is there some other way that's used to determine it's a function object? What does "packing pointers" to the instance object mean? What's an abstract object?
 
     
     
    