TypeError: func() missing 1 required positional argument: 'self'
How to Set Function as Methods
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
.
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))