Python全栈day28(类的装饰器)
类是一个对象也可以像函数一样加装饰器
类的装饰器.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | def deco(obj): print ( '======' ,obj) obj.x = 1 obj.y = 2 obj.z = 3 return obj # @deco #test=deco(test) # def test(): # print('test函数运行') <br> #运行了装饰器所以打印了装饰器里面的print内容 @deco #Foo=deco(Foo)<br>#====== class Foo: pass <br> #打印类的字典,其中xyz属性是在装饰器函数里面定义的 print (Foo.__dict__) #{'__doc__': None, 'z': 3, 'y': 2, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, 'x': 1, '__module__': '__main__'} |
本装饰器就是把类作为实参传递给函数deco然后把返回值赋值给Foo,在装饰器函数里面可以定义对应类的属性
以上装饰器虽然在装饰器里面实现了对类属性进行赋值但是把赋值写死了
下面通过嵌套把装饰器写的灵活
类的装饰器2.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #定义装饰器函数deco函数接受参数为字典格式 def deco( * * kwargs): def wrapper(obj): print ( '--->' ,kwargs) #---> {'y': 2, 'z': 3, 'x': 1} print ( '类名--->' ,obj) #类名---> <class '__main__.Foo'> for key,val in kwargs.items(): setattr (obj,key,val) return obj print ( '===>' ,kwargs) #===> {'y': 2, 'z': 3, 'x': 1} return wrapper #在原装饰器deco嵌套一个内部函数wrapper #执行步骤 #1,deco(x=1,y=2,z=3)执行函数deco返回的是函数wrapper #2,@wrapper装饰类Foo 相当于把类Foo作为参数传递给函数wrapper然后再返回给Foo #3,在函数wrapper内部执行对应的对类属性执行赋值操作使用了函数setattr,传递3个参数1位对象2为key3为value @deco (x = 1 ,y = 2 ,z = 3 ) #deco(x=1,y=2,z=3) -->@wrapper class Foo: pass print (Foo.x) #1 #同理使用装饰器装饰另外一个类可以通过在装饰的时候传递参数实现对不同类装饰的定制 @deco (name = 'zhangsan' ) class Bar: pass #装饰成功打印正确 print (Bar.name) #zhangsan |
类的装饰器的应用.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | class Typed: def __init__( self ,key,expected_type): self .key = key self .expected_type = expected_type def __get__( self , instance, owner): print ( 'get方法' ) # print('instance是[%s]'%instance) # print('owner是[%s]'%owner) #使用对应的key返回值 return instance.__dict__[ self .key] def __set__( self , instance, value): print ( 'set方法' ) #instance就是实例化出来的对象本身 # print('instance是[%s]'%instance) # print('value是[%s]'%value) #对应的key进行赋值设置操作 if not isinstance (value, self .expected_type): # print('你输入是不是字符串类型,错误') # return raise TypeError( '%s你传入的不是%s' % (value, self .expected_type)) instance.__dict__[ self .key] = value def __delete__( self , instance): print ( 'delete方法' ) # print('instance是[%s]' % instance) #使用对应的key删除操作 instance.__dict__.pop( self .key) def deco( * * kwargs): def wrapper(obj): for key,val in kwargs.items(): print ( '=====>' ,key,val) #第一次循环key='name' val='str' #相当于给类加了对应的类属性设置为描述符 #完成了之前People类里面的name = Typed('name',str) setattr (obj,key,Typed(key,val)) return obj return wrapper @deco (name = str ,age = int ) class People: # name = Typed('name',str) # age = Typed('age',int) def __init__( self ,name,age,salary): self .name = name self .age = age self .salary = salary p1 = People( 'zhangsan' , 18 , 999999 ) print (p1.__dict__) |
把之前通过描述符实现的对类型限制的功能使用装饰器实现,简化代码
使用装饰器来给类属性添加一个属性,只不过这个属性比较特殊,是一个描述符
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!