裝飾器函式其實是這樣乙個介面約束,它必須接受乙個callable物件作為引數,然後返回乙個callable物件。在python中一般callable物件都是函式,但也有例外。只要某個例項物件重寫了call() 方法,那麼這個物件就是callable的。
不帶引數的類裝飾器
class
test
(object):
def__init__
(self, func):
print("---初始化---")
print("func name is %s"%func.__name__)
self.__func = func
def__call__
(self):
print("---裝飾器中的功能---")
self.__func()
@test #相當於test = test(test)
deftest
(): print("----test---")
test()
說明:
1. 當用test來裝作裝飾器對test函式進行裝飾的時候,首先會建立test的例項物件並且會把test這個函式名當做引數傳遞到init方法中即在init方法中的屬性__func指向了test指向的函式;
2. test指向了用test建立出來的例項物件;
3. 當在使用test()進行呼叫時,就相當於讓這個物件(),因此會呼叫這個物件的call方法;
4. 為了能夠在call方法中呼叫原來test指向的函式體,所以在init方法中就需要乙個例項屬性來儲存這個函式體的引用所以才有了self.func = func這句**,從而在呼叫__call方法中能夠呼叫到test之前的函式體。
執行結果如下:
---
初始化---
func
name
istest--
-裝飾器中的功能--
----
-test--
-
帶引數的類裝飾器class
log(object):
def__init__
(self, num):
self.num = num # self.num---->666 # 儲存引數
def__call__
(self, func):
self.func = func # 儲存原函式的引用
return self.call_func
defcall_func
(self, *args, **kwargs):
# 這裡新新增的功能......
print(self.num) # 獲取裝飾的時候的引數
return self.func(*args, **kwargs) # 呼叫被裝飾的函式
@log(666)
deftest
(): print("-------test----")
test()
呼叫log(666)—->用log建立乙個例項物件,將1當做實參傳遞到init方法中;
呼叫例項物件對test函式進行裝飾,可以理解為 test = 例項物件(test) ,裝飾完成之後,test指向了__call__
方法中返回的self.call_func
方法
執行結果如下:
666--
----
-test--
--
類當作裝飾器的意義
如果裝飾器想實現的功能比較少,那我們用普通的裝飾器即可,但如果我們想實現多種功能,會在乙個裝飾器裡寫很多**,顯然用普通的裝飾器實現起來很費勁,但如果用類裝飾器的話,我們可以把各種功能封裝在乙個個例項方法中,然後在__call__
方法中呼叫不同的例項方法。
python 高階 類當作裝飾器
類在建立物件時,會呼叫 init 初始化一些東西 然後 如果類中定義了 call 方法,可以直接用 物件 這種方法呼叫,所以可以用類來裝飾函式 class test object def init self,func print 裝飾 print func name is s func.name s...
python中類作為裝飾器
class test object print test t test t traceback most recent call last file f python專案 09day 03python高階 01類作為裝飾器.py line 6,in t typeerror test object i...
python裝飾器 函式裝飾器,類裝飾器
只要實現此 模式,這個obj就叫乙個裝飾器 參考 函式裝飾器 例子 def decorator func def inner args,kwargs print before.res func args,kwargs print after.return res return inner decor...