Could bound methods be implemented without instantiating MethodType on each call?

48 views Asked by At

As the docs say, functions defined in the class body are bound to class instance on demand (that is, when they're called by that instance); function object is a non-data descriptor.

This is indeed the case:

>>> class X:
...     def foo(self): 1
... 
>>> x = X()
>>> print(hex(id(x.foo)))  # 0x7fe59020fa40
... after several seconds ...
>>> print(hex(id(x.foo)))  # 0x7fe59020fbc0 <- different!
>>> print(x.foo is x.foo)  # False

Pure Python equivalent of function's __get__ is:

def __get__(self, instance, owner=None):
    "Simulate func_descr_get() in Objects/funcobject.c"
    if instance is None:
        return self
    return MethodType(self, instance)

Wouldn't it be more efficient not to create an instance of MethodType, but instead just return a small wrapper? In pure Python:

def __get__(self, instance, owner=None):
    "Simulate func_descr_get() in Objects/funcobject.c"
    def new_func(*args, **kwargs):
        return self(instance, *args, **kwargs)
    return new_func if instance is not None else self

Naturally, all of this isn't written in pure Python but instead, in CPython case, it's written in C; there are probably various shortcuts on the way. But surely in C (for CPython) defining a small wrapper function is faster than instantiating a MethodType? Or not?

I'm curious why wasn't this way chosen... What drawbacks does it have, compared to instantiating MethodType on each call?

0

There are 0 answers