In Python, when a method is declared, in the body of the function it is exactly like a function - as soon as the class is parsed and exists, retrieving the method through ".". the operator converts this function - on the fly - into a method. This conversion adds the first parameter to the method (if it is not a static method) -
So:
>>> class A(object): ... def b(self): ... pass ... >>> Ab is Ab False
Make sure that each extraction of attribute โbโ in โAโ gives a different instance of โmethod object bโ
>>> Ab <unbound method Ab>
The original function "b" can be obtained without any trasnform if you do
>>> A.__dict__["b"] <function b at 0xe36230>
The same thing happens for the function decorated with @classmethod , and the value "class" is added to the parameter list when it is extracted from A.
The decorators @classmethod and @staticmethod main function in a different descriptor than the regular instance method. The classmethod object โ what a function is when it is wrapped with classmethod โ is a handle object that has a __get__ method that returns a function that wraps the base function and adds the cls parameter before everyone else.
Any additional decorator for @classmethod should โknowโ, it is actually dealing with a handle object, not a function. -
>>> class A(object): ... @classmethod ... def b(cls): ... print b ... >>> A.__dict__["b"] <classmethod object at 0xd97a28>
Thus, it is much easier to let the @classmethod decorator be the last to be applied to the method (the first on the stack) so that other decorators work on a simple function (knowing that the cls argument will be inserted as the first).
source share