Functions are descriptors and use the descriptor protocol to bind the instance the method is called on to the first argument. This is how "self works". So, if you look at the Descriptor HOWTO it gives you an example of how it would be implemented in Python:
class Function:
...
def __get__(self, obj, objtype=None):
"Simulate func_descr_get() in Objects/funcobject.c"
if obj is None:
return self
return MethodType(self, obj)
So, here are examples of calling the returned callable with different types of objects:
>>> def frobnicate(first):
... return first.foo + 1
...
>>> class Foo:
... foo = 42
...
>>> class Bar:
... foo = "bar"
...
>>> class Baz:
... bar = 42
...
>>> frobnicate.__get__(Foo())()
43
>>> frobnicate.__get__(Bar())()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in frobnicate
TypeError: can only concatenate str (not "int") to str
>>> frobnicate.__get__(Baz())()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in frobnicate
AttributeError: 'Baz' object has no attribute 'foo'
And of course, putting the function in some class namespace makes it act like any other method automatically:
>>> Foo.frobnicate = frobnicate
>>> Foo().frobnicate()
43
Note, you can mentally think of MethodType as just something like:
def bind_first(func, obj):
def bound(*args, **kwargs):
return func(obj, *args, **kwargs)
return bound
Although, if you check the link, it shows a closer implementation (in Python, instead of C):
Methods can be created manually with types.MethodType which is roughly equivalent to:
class MethodType:
"Emulate PyMethod_Type in Objects/classobject.c"
def __init__(self, func, obj):
self.__func__ = func
self.__self__ = obj
def __call__(self, *args, **kwargs):
func = self.__func__
obj = self.__self__
return func(obj, *args, **kwargs)
Which is basically doing the same thing as the bind_first function I gave as an example... (although, again, it's using a class and it also creates the __func__ and __self__ arguments that bound-methods have).