--------------------------------------------------------------------------- TypeError Traceback (most recent call last) /var/folders/vv/syvp2m7117s_1y8m9bwlj28m0000gq/T/ipykernel_61591/1654612476.py in <module> 6 return 1 7 ----> 8 A.func() 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))