__call__是一个很神奇的特性,只要某个类型中有__call__方法,,咱们能够把这个类型的对象看成函数来使用。python
也许说的比较抽象,举个例子就会明白。函数
In [107]: f = abs In [108]: f(-10) Out[108]: 10 In [109]: dir(f) Out[109]: ['__call__', '__class__', '__delattr__', '__dir__', ...]
上例中的f对象指向了abs类型,因为f对象中有__call__方法,所以f(-10)实现了对abs(-10)的重载。spa
ps:因为变量/对象/实例能够指向函数,而函数可以接受变量,所以能够看出函数能够接受另外一个函数做为参数,因此__call__就实现装饰器的基础。code
扩展部分:返回函数对象
函数或类通常有返回值,而python中有一个神奇的特性就是返回函数。blog
In [134]: %cpaste Pasting code; enter '--' alone on the line to stop or use Ctrl-D. : :def lazy_sum(*args): : def sum(): : ax = 0 : for n in args: : ax = ax + n : return ax : return sum :-- In [135]: f = lazy_sum(1,3,5,7,9) In [136]: f Out[136]: <function __main__.lazy_sum.<locals>.sum> In [137]: f() Out[137]: 25
为何返回函数可以这么神奇,我们一探究竟。get
In [138]: dir(f) Out[138]: ['__annotations__', '__call__', '__class__', ... '__getattribute__', ... '__setattr__', ]
查看一下type,真相战胜,原来是由于f里有__call__的内建方法。io