0

The following code works:

class Foo:
    def run_this(self):
        print("ran this")

ff = Foo()
method = getattr(ff, "run_this")
method()
--
run_this

But I don't understand why. If getattr returns a function object should I need to pass self to the object as the first argument. It seems that method is not a function object after all, but I'm not sure what it is then. Why does self get passed when I call method()?

The docs say only

getattr(object, name[, default]) Return the value of the named attribute of object. name must be a string. If the string is the name of one of the object’s attributes, the result is the value of that attribute. For example, getattr(x, 'foobar') is equivalent to x.foobar. If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised.

So they answer the "what happens" question, but not the question of why it works this way.

Ray Salemi
  • 5,247
  • 4
  • 30
  • 63
  • 3
    `getattr(obj, 'method')()` doesn't need a `self` argument for the same reason `obj.method()` doesn't - it's already bound to the object when you look up the attribute. Without an explanation of why you think `getattr` with a string literal should behave differently from normal attribute access, I am not sure what other answer would satisfy you. – kaya3 Dec 31 '20 at 12:18
  • 1
    `getattr(obj, 'method')` returns a "bound method", which is essentially the same thing as a `functools.partial` method with the first argument bound to `obj` – Iain Shelvington Dec 31 '20 at 12:20
  • Because it is equivalent to `method = ff.run_this`, which for the same reason doesn't require `self` as an argument. The same reason `ff.run_this()` doesn't – juanpa.arrivillaga Dec 31 '20 at 12:25
  • 1
    If you want to understand how all of this fundamentally works, you need to understand that function objects are descriptors who's `__get__` method partially applies the instance when accessed on an instance. Read the following: https://docs.python.org/3/howto/descriptor.html – juanpa.arrivillaga Dec 31 '20 at 12:27

0 Answers0