Python › Descriptors & Properties

How does Python's own implementation of instance methods use the descriptor protocol to achieve automatic 'self' binding?

Advanced

Answer

Functions are non-data descriptors — a plain function's __get__ method, when accessed through an INSTANCE, returns a BOUND METHOD object with 'self' automatically pre-filled as the first argument; accessed through the CLASS directly, it returns the plain, unbound function — this is the exact mechanism underlying Python's automatic method binding.
class Example:
    def greet(self):
        return "Hello!"

e = Example()
print(Example.greet)     # <function Example.greet at ...> -- unbound, plain function
print(e.greet)           # <bound method Example.greet of <Example object>> -- 'self' auto-bound
print(e.greet())         # "Hello!" -- self was automatically supplied
Real-world example Understanding the actual mechanism (function.__get__) that makes 'self' automatically get passed to instance methods without you doing it manually.

Common follow-ups: Would a staticmethod-wrapped function behave the same way when accessed through an instance, or differently?