Descriptors: Bound Method#

Ways To Call A Method#

class Person:
    def __init__(self, name):
        self.name = name
    def greet(self, phrase):           # <-- method
        print(f'{phrase} {self.name}')

joerg = Person('Joerg')

Two ways to call greet …

“On the object” directly (as everybody does everyday), supplying one parameter. joerg is “implicitly” passed as self.

joerg.greet('Howdy, my name is')
Howdy, my name is Joerg

Via the class, supplying the object explicitly, as self.

Person.greet(joerg, 'Howdy, my name is')
Howdy, my name is Joerg

Bound Methods#

Bound method

print(joerg.greet)
<bound method Person.greet of <__main__.Person object at 0x7f9dc5eb1a90>>
greetfunc = joerg.greet
greetfunc('Howdy, my name is')
Howdy, my name is Joerg

So, obviously a bound method brings the object with it!

Plain function: knows no object

print(Person.greet)
<function Person.greet at 0x7f9dc5e97ed0>

Using functools.partial to get “bound method” behavior:

from functools import partial
greetfunc = partial(Person.greet, joerg)
greetfunc('Howdy, my name is')
Howdy, my name is Joerg

And Descriptors?#

  • joerg.greet is an attribute ⟶ descriptor protocol

  • Somehow I get a bound method when I say joerg.greet

  • So where is the descriptor?

  • ⟶ It’s the function Person.greet itself!

print(Person.greet.__get__)     # <-- A-HA!!
<method-wrapper '__get__' of function object at 0x7f9dc5e97ed0>