在文章神奇的python鏈式調用中,提到一個疑惑,函數和對象一樣麼
思考
- 一樣的話說明函數也有屬性,那麼函數真的有麼
- 函數和對象一樣可以動態添加屬性麼
- 函數也是類的實例麼
- 對象也可以調用麼
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。