I am having trouble understanding why the following happens. I am having a decorator which does nothing except it checks whether a function is a method. I thought I have understood what method in Python is, but obviously, this is not the case:
import inspect
def deco(f):
def g(*args):
print inspect.ismethod(f)
return f(*args)
return g
class Adder:
@deco
def __call__(self, a):
return a + 1
class Adder2:
def __call__(self, a):
return a + 2
Adder2.__call__ = deco(Adder2.__call__)
Now, running the following:
>>> a = Adder()
>>> a(1)
False
2
>>> a2 = Adder2()
>>> a2(1)
True
3
I would expect for this code to print True two times.
So, decorating the function manually as in the Adder2 is not an exact equivalent to decorating via the @deco function?
Can someone be so glad and explain why this happens?
Inside a class definition, __call__
is a function, not a method. The act of accessing the function through attribute lookup (e.g. using the dot syntax), such as with Adder2.__call__
, returns an unbound method. And a2.__call__
returns a bound method (with self
bound to a2
).
Note that in Python3 the concept of unbound method
has been dropped. There, Adder2.__call__
is a function as well.