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


__call__是一個很神奇的特性,只要某個類型中有__call__方法,,我們可以把這個類型的對象當作函數來使用。

也許說的比較抽象,舉個例子就會明白。

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)的重載。

 

ps:由於變量/對象/實例可以指向函數,而函數能夠接受變量,因此可以看出函數可以接受另一個函數作為參數,所以__call__就實現裝飾器的基礎。

 

擴展部分:返回函數

函數或類一般有返回值,而python中有一個神奇的特性就是返回函數

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

為什么返回函數能夠這么神奇,咱們一探究竟。

In [138]: dir(f)
Out[138]: 
['__annotations__',
 '__call__',
 '__class__',
 ...
 '__getattribute__',
...
 '__setattr__',
]

查看一下type,真相打敗,原來是因為f里有__call__的內建方法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM