类装饰器

类的装饰器:

无参:

# 高级函数
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>

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值