类的装饰器:
无参:
# 高级函数
def deco(obj):
print('----->',obj)
obj.x = 1
obj.y = 2
return obj
@deco # Foo = deco(Foo)
class Foo:
pass
print(Foo.__dict__) # {'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 'x': 1, 'y': 2}
# f1 = Foo()
# print(f1.__dict__)
有参:
def Typed(**kwargs):
def deco(obj):
# print('---->',kwargs)
# print('---->',obj)
for k,v in kwargs.items():
setattr(obj,k,v)
return obj
return deco
@Typed(x=1,y=2) # 1.Typed(x=1,y=2) ---> doce 2.@deco -----> Foo = deco(Foo)
class Foo:
pass
@Typed(name='long') # 1.Typed(name='long') ---> doce 2.@deco -----> Foo = deco(Foo)
class Bar:
pass
print(Foo.__dict__)
print(Bar.__dict__)
'''
{'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 'x': 1, 'y': 2}
{'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Bar' objects>, '__weakref__': <attribute '__weakref__' of 'Bar' objects>, '__doc__': None, 'name': 'long'}
'''
类装饰器的应用举例
#描述符
class Typed:
def __init__(self,key,key_type):
self.key = key
self.key_type = key_type
def __get__(self, instance, owner):
print('get方法')
# print('instance参数:%s'%instance) # People object
# print('owner参数:%s'%owner)
return instance.__dict__[self.key]
def __set__(self, instance, value):
# 代理的好处:可以对传进来的值进行下一步判断
print('set方法')
# print('instance参数:%s'%instance) # People Object
# print('value参数:%s'%value)
if not isinstance(value,self.key_type):
raise TypeError('%s不是%s'%(value,self.key_type))
instance.__dict__[self.key] = value
def __delete__(self, instance):
print('delete方法')
# print('instance参数:%s'%instance) # People object
instance.__dict__.pop(self.key)
def deco(**kwargs): # kwargs = {name:str,age:int}
def wrapeer(obj): # obj = People
for k,v in kwargs.items():
# Typed(k,v)描述符
setattr(obj,k,Typed(k,v)) # People.name = Typed('name',str)
return obj
return wrapeer
@deco(name=str,age=int) # 1.deco(name=str,age=int) ————>wrapeer 2.@wrapeer --> People = wrapeer(People)
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('long',18,8000)
print(People.__dict__)
print(p1.__dict__)
'''
set方法
set方法
{'__module__': '__main__', '__init__': <function People.__init__ at 0x000002632A6A61E0>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None, 'name': <__main__.Typed object at 0x000002632A6A5D68>, 'age': <__main__.Typed object at 0x000002632A6A5DD8>}
{'name': 'long', 'age': 18, 'salary': 8000}
'''
自定义@property(装饰器也可以是类)
# 装饰器
class Lazyproperty:
def __init__(self,func):
# print(func,'------->') # <function Room.area at 0x0000021FADF36048> ------->
self.func = func
def __get__(self, instance, owner):
print('get')
# print(self) # <__main__.Lazyproperty object at 0x00000289DCCF5B38>
# print(instance) # <__main__.Room object at 0x0000019455B45C18>
# print(owner) #<class '__main__.Room'>
if instance == None:
return self
return self.func(instance)
class Room:
def __init__(self,name,width,length):
self.name = name
self.width = width
self.length = length
# @property # area = property(area)
@Lazyproperty # area = Lazyproperty(area) # area 属性被代理,描述符
def area(self):
return self.width * self.length
@property
def area1(self):
return self.width * self.length
print(Room.__dict__) # 'area': <__main__.Lazyproperty object at 0x000001FE5615A358>
r1 = Room('厕所',1,2) # 2
print(r1.area)
print(Room.area1) # 类调用 <property object at 0x000001BBF5306908>
print(Room.area) # <__main__.Lazyproperty object at 0x000002EC45AAA828>