class foo(object):
def __init__(self, func):
self._test = func #隱藏
def __call__(self):
print ('call start')
self._test()
print ('call end')
if __name__ == '__main__':
@foo
def test():
testbox1 = int(input(u"我是:"))
test()
'''
'''
#x.py
<import做使用>
__call__就是可被調用(任何可呼叫的調用皆可)。
但須注意__call__在作用域位置,像此程式賦予hide變數,又做調用就可以達到類似資料保護的功能。
如要做完整的模板,可做個陣列做寫入(陣列裡資料需寫進封裝函式內)。
內建裝飾器最複雜的一種用法,因為它不只單是個裝飾器 功能還蠻多的。
@staticmethod跟@classmethod可把類別物件化直接調用。而@property就是用來把方法或物件類別化。
像剛剛的程式,如果想要檢查資料完整性但又不能動到資料該怎麼辦?
這時就動用@property把檢查函式轉換為class使用,
class foo(object):
def __init__(self, func):
self._test = func #隱藏
def __call__(self):
print ('call start')
self._test()
print ('call end')
@property #class
def check(self):
return self._test
if __name__ == '__main__':
@foo
def test():
testbox1 = int(input(u"我是:"))
return 5**12345
test()
foo.check
結果發現果然只加入某些功能,主class"foo"可視test()為附加功能。
最好的實例就是紀錄執行時間:
因為紀錄時間常常需動用裡面的變數,而變數出bug也會影響時間函式。所以就可把時間函式當裝飾器,萬一不能執行也不影響結構。
import time
def timmer(func):
start = time.time()
func()
end = time.time()
print(end - start) #計算總延遲
@timmer
def massage():
time.sleep(0.5) #..
print("this")
time.sleep(0.5) #..
print("is")
time.sleep(0.5) #delay0.5
print("massage")
@property #轉換class做調用
def massage2():
return "end all"
massage2
裝飾器因2度裝飾,造成massage2()值為None。這時偷吃步把它轉為屬性就ok了。