python裝飾器實現函數註冊和類裝飾器

一 裝飾器實現回調函數註冊

******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

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