一 裝飾器實現回調函數註冊
******01 一般情況下都是使用函數作爲裝飾器,其實class也是可以的,function是callable對象,class只有重寫了__call__方法後,它的實例對象也就是callable對象了。
******02 裝飾器的嵌套:就一個規律:嵌套的順序和代碼的順序是相反的。
class FunctionManager:
def __init__(self):
print("初始化")
self.functions = []
def execute_all(self):
for func in self.functions:
func()
def register(self, func):
self.functions.append(func)
fm = FunctionManager()
@fm.register
def t1():
print("t1")
@fm.register
def t2():
print("t2")
@fm.register
def t3():
print("t3")
fm.excute_all()
# 結果如下:
初始化
t1
t2
t3
二 用裝飾器獲取類信息
def class_info():
def wrapper(cls):
print(cls.__name__)
#print(cls.__dict__)
return wrapper
@class_info() # Test = class_info(Test)
class Test:
a = 1
b = "123"
c = ["66","666"]
d = {"name": "foxyball"}
輸出結果:
Test
三 函數和類分別做修飾器
******本質上裝飾器就是一個返回函數的高階函數,它接收一個函數,並返回一個函數,用法就是在被裝飾的函數上面加上@裝飾器函數名。
3.1 函數做修飾器, 類被修飾
def wrap(tmp_obj):
print("裝飾器------")
tmp_obj.x = 1
tmp_obj.y = 3
tmp_obj.z = 5
return tmp_obj
******@wrap #將類Foo作爲一個參數傳入[類地址]修飾器wrap,返回該對象,同時把新對象重新命名爲Foo, 即Foo = wrap(Foo)
class Foo:
pass
輸出結果:
裝飾器------
print(Foo.__dict__)
#輸出結果,新的Foo類新增了x,y,z屬性
3.2 函數做修飾器,另一個函數做被修飾器
# 函數可以作爲一個對象,也有__dict__方法
def wrap(obj):
print("裝飾器------")
obj.x = 1
obj.y = 3
obj.z = 5
return obj
@wrap # test = wrap(test)
def test():
print("test ------ ")
test.x = 10 # test的x屬性被重新賦值
3.3 類做修飾器,函數被修飾
import time
class Test:
def __init__(self,func):
self.func = func
def __call__(self,*args,**kwargs):
print("123")
start_time = time.time()
self.func(*args,**kwargs)
time.sleep(2)
end_time = time.time()
return (end_time - start_time)
******@Test # test1 = Test(test1) test1實例化Test 傳入test1的函數地址
def test1(a):
print("測試一下類裝飾器%s" % a)
test1("123")
# __call__():給實例化賦予函數功能,運行實例化後的test1 就等價於運行__call__()
3.4 類做修飾器,類被修飾
class ShowClassName(object):
def __init__(self, cls):
self._cls = cls
def __call__(self, a):
print("class name:", self._cls.__name__)
@ShowClassName
class Foobar(object):
def __init__(self, a):
self.value = a
def fun(self):
print(self.value)
a = Foobar("xiemanR")
a.fun()
reference:
https://foofish.net/python-decorator.html
https://blog.csdn.net/gezailushang/article/details/84291092?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task