__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