Python3基础-类的装饰器
函数的装饰器
#函数的装饰器 def deco(func): print("deco======") return func @deco #test = deco(test) def test(): print("test=====") test() """ 执行结果: deco====== test===== """
一切皆对象
eg:
#一切皆对象 def test(): print("-----test----") test.x =1 test.y =2 print(test.__dict__)
以上代码执行结果如下:
{'x': 1, 'y': 2}
类的装饰器
#类的装饰器
def deco(obj):
print("deco======",obj) #输出的是 deco====== <class '__main__.test'>
obj.x = 1 #添加test的类的数字属性
obj.y = 2 #添加test的类的数字属性
return obj
@deco #test = deco(test)
class test:
def __init__(self,name):
self.name = name
def testFunc(self):
print("======",self.name)
print(test) #输出的是 <class '__main__.test'>
print(test.__dict__)
"""
执行结果:
deco====== <class '__main__.test'>
<class '__main__.test'>
{'__module__': '__main__', '__init__': <function test.__init__ at 0x0307F6A8>, 'testFunc': <function test.testFunc at 0x0307F780>, '__dict__': <attribute '__dict__' of 'test' objects>, '__weakref__': <attribute '__weakref__' of 'test' objects>, '__doc__': None, 'x': 1, 'y': 2}
"""
因为obj.x =1 obj.y =2 固定写死了,如何灵活运用
def tesDeco(**kwargs): def deco(obj): # print("deco======",obj) #输出的是 deco====== <class '__main__.test'> # print("kwargs",kwargs) for key,value in kwargs.items(): # print(key,value) setattr(obj,key,value) return obj print("====kwargs",kwargs) return deco @tesDeco(a=1,b=2) #tesDeco(x=1,y=2)-->deco @deco test = deco(test) class test: def __init__(self,name): self.name = name def testFunc(self): print("======",self.name) print(test.__dict__)
以上代码执行结果如下:
====kwargs {'a': 1, 'b': 2} {'__module__': '__main__', '__init__': <function test.__init__ at 0x0110F780>, 'testFunc': <function test.testFunc at 0x0110F7C8>, '__dict__': <attribute '__dict__' of 'test' objects>, '__weakref__': <attribute '__weakref__' of 'test' objects>, '__doc__': None, 'a': 1, 'b': 2}
在循环读取kwargs.items()时
错误 eg1
def tesDeco(**kwargs): def deco(obj): # print("deco======",obj) #输出的是 deco====== <class '__main__.test'> # print("kwargs",kwargs) for key,value in kwargs.items(): obj.__dict__[key]=value #不允许这样写,会报错TypeError: 'mappingproxy' object does not support item assignment return obj print("====kwargs",kwargs) return deco
错误 eg2
def tesDeco(**kwargs): def deco(obj): # print("deco======",obj) #输出的是 deco====== <class '__main__.test'> # print("kwargs",kwargs) for key,value in kwargs.items(): obj.key =value # 最后写入类属性的是{'key':2} return obj print("====kwargs",kwargs) return deco
类的装饰器的应用
class Desc(): def __init__(self,key,expected_type): self.key = key self.expected_type = expected_type def __get__(self, instance, owner): print("__get__") return instance.__dict__[self.key] #获取 def __set__(self, instance, value): print("__set__") if not isinstance(value,self.expected_type): raise TypeError("%s 类型必须输入%s类型"%(self.key,self.expected_type)) instance.__dict__[self.key]=value #写入 def __delete__(self, instance): print("__delete__") instance.__dict__.pop(self.key) def tesDeco(**kwargs): def deco(obj): # print("deco======",obj) #输出的是 deco====== <class '__main__.test'> # print("kwargs",kwargs) for key,value in kwargs.items(): print('===',key,value) setattr(obj,key,Desc(key,value)) #新增people的属性 ==》name = Desc('name',str) return obj print("====kwargs",kwargs) return deco @tesDeco(name=str,age=int) class People(): # name = Desc('name',str) # age = Desc('age',int) def __init__(self,name,age,salary): self.name = name self.age = age self.salary = salary print(People.__dict__) p1 = People('su',30,100)