你不知道的事:python的函數和對象本爲一家

在文章神奇的python鏈式調用中,提到一個疑惑,函數和對象一樣麼

思考

  1. 一樣的話說明函數也有屬性,那麼函數真的有麼
  2. 函數和對象一樣可以動態添加屬性麼
  3. 函數也是類的實例麼
  4. 對象也可以調用麼

def testFunc():
    pass

def testSubFunc():
    print('sub func!')

if __name__ == '__main__':
    # 動態加入屬性
    testFunc.someAttr = 11
    print( testFunc.someAttr )
    # 動態加入方法
    testFunc.subFunc = testSubFunc
    # 調用動態加入的方法
    testFunc.subFunc()
    print( dir(testFunc) )
    print( type(testFunc) )

該例子中,我們定義了一個函數testFunc,如果函數和對象一樣,那麼第一點,他有屬性,他還可以動態加入屬性,包括靜態屬性和方法,於是我們進行了驗證,輸出如下:

11
sub func!
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'someAttr', 'subFunc']
<class 'function'>

由此可以看出,函數也是一個對象,他本身有很多的屬性和方法,還能動態加入屬性和方法,他是類function的一個實例。

那麼對象也可以調用麼?是的,類對象實現__call__方法後是可以直接調用的。

class testclass(object):
    def __call__(self):
        print('對象調用')
def testSubFunc():
    print('sub Func!')

if __name__ == '__main__':
    # 動態加入屬性
    testclass.someAttr = 11
    print( testclass.someAttr )
    # 動態加入方法
    testclass.subFunc = testSubFunc
    # 調用動態加入的方法
    testclass.subFunc()
    print( dir(testclass) )
    print( type(testclass) )
    
    instance = testclass()
    instance()
    print(callable(testclass))

如上,定義類是重寫了__call__方法,於是實例可以直接調用,當然call可以加入處理self以外的參數。

另外: 這和直接調用類不一樣,直接調用類是創建實例,相關方法是init。也不能先實例化對象後,給對象添加call方法

可以直接調用的是一個callable對象,可以使用 callable(testclass)進行判斷,可以直接調用的對象返回true,當然,函數返回的是true。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章