How to Set Function as Methods

Python
How to set a function as bound method, class method and property.
Author

Ziyue Li

Published

December 4, 2022

TIL: In python, functions act as descriptors. When they are called from an instance, they get turned into “bound method”, which automatically inserts the instance into the function as its first argument: obj.f(*args) call is transformed into f(obj, *args). If they are called from a class, we get the function itself, and we need to provide all the arguments ourselves: Calling cls.f(*args) becomes f(*args).

In the following example, A.func() raises error because it expects one argument, while A().func() runs without a problem because A() is automatically inserted into the func.

class A:
    def __init__(self):
        pass

    def func(self):
        return 1

A.func()
TypeError: func() missing 1 required positional argument: 'self'
A().func()
1

Because this behavior is associated with functions (those defined with def) themselves, we don’t need to do anything different if we want to turn a function into a method. However we write them in the class definition, we can do the same thing here.

Additionally, we can use MethodType to return a method that automatically inserts the object’s class as the first argument, equivalent to using the classmethod decorator.

from types import MethodType

class A:
    x = 10

    def __init__(self):
        self.xx=100

def func(cls):
    return cls.x + 1

def ins_func(self):
    return self.xx + 1


# Set a function as method
setattr(A, 'func', ins_func)
# Set a function as classmethod
setattr(A, 'class_func1', MethodType(func, A))
setattr(A, 'class_func2', classmethod(func))
# Set a function as property
setattr(A, 'property_func', property(ins_func))
A.class_func1()
A.class_func2()
A().class_func1()
A().class_func2()
11
11
11
11
a = A()
a.func
a.func()
<bound method ins_func of <__main__.A object at 0x7f9f40b79b50>>
101
a.property_func
101