python的高級特性3:神奇的__call__與返回函數

__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

相關文章
相關標籤/搜索