Let's start with the code:
def func(*x): print('func:', x) class ABC: def __init__(self, f): self.f1 = f def f2(*x): print('f2:', x)
Now we will conduct some tests:
>>> a = ABC(func) >>> a.f1(10) func: (10,) >>> a.f2(10) f2: (<__main__.ABC object at 0xb75381cc>, 10) >>> a.f3 = func >>> a.f3(10) func: (10,) >>> a.f1 <function func at 0xb74911ec> >>> a.f2 <bound method ABC.f2 of <__main__.ABC object at 0xb75381cc>> >>> a.f3 <function func at 0xb74911ec>
Note that func is a normal function, and we make it the f1 method for the class.
We see that f2 receives an instance of the class as the first argument, but f1 and f3 are not, although all functions are called class methods. We can also see that if we call a normal function as a class method, Python does not make a related method out of it.
So, why does f1 or f3 NOT get the class instance passed to it even when we call it as a class method? And also, as Python knows, we call an external function as a method so that it does not pass an instance to it.
- EDIT -
OK, so basically what I'm doing wrong is that I bind the functions to the instance, and NOT to the class object itself. Therefore, these functions simply become attributes of the instance. We can verify this with:
>>> ABC.__dict__ ... contents... >>> a.__dict__ {'f1': <function func at 0xb74911ec>, 'f3': <function func at 0xb74911ec>}
Also note that this dict cannot be assigned:
>>> ABC.__dict__['f4'] = func TypeError: 'dict_proxy' object does not support item assignment