.. include:: Descriptors: Bound Method ========================= Ways To Call A Method --------------------- .. jupyter-execute:: 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. .. jupyter-execute:: joerg.greet('Howdy, my name is') **Via the class**, supplying the object explicitly, as ``self``. .. jupyter-execute:: Person.greet(joerg, 'Howdy, my name is') Bound Methods ------------- **Bound method** .. jupyter-execute:: print(joerg.greet) .. jupyter-execute:: greetfunc = joerg.greet greetfunc('Howdy, my name is') So, obviously a bound method brings the object with it! **Plain function**: knows no object .. jupyter-execute:: print(Person.greet) Using :doc:`functools.partial ` to get "bound method" behavior: .. jupyter-execute:: from functools import partial greetfunc = partial(Person.greet, joerg) greetfunc('Howdy, my name is') And Descriptors? ---------------- * ``joerg.greet`` is an attribute |longrightarrow| :ref:`descriptor protocol ` * Somehow I get a *bound method* when I say ``joerg.greet`` * So where is the descriptor? * |longrightarrow| It's the function ``Person.greet`` itself! .. jupyter-execute:: print(Person.greet.__get__) # <-- A-HA!!