类的装饰器

实现给类添加属性

def Typed(**kwargs):
    def deco(obj):
        for key,val in kwargs.items():
            # obj.key = val
            setattr(obj,key,val)
        return obj
    print('==>',kwargs)
    return deco

@Typed(x=1,y=2,z=3)
class Foo:
    pass

# f = Foo()
print(Foo.__dict__) #给Foo类添加属性成功
#{'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 'x': 1, 'y': 2, 'z': 3}

@Typed(name='ago')
class Bar:
    pass

print(Bar.__dict__)
'''
==> {'x': 1, 'y': 2, 'z': 3}
{'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 'x': 1, 'y': 2, 'z': 3}
==> {'name': 'ago'}
{'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Bar' objects>, '__weakref__': <attribute '__weakref__' of 'Bar' objects>, '__doc__': None, 'name': 'ago'}
'''

实现输入的类型判断

class Typed:
    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 deco(**kwargs): #kwargs={'name':str,'age':int}
    def wrapper(obj): #obj=People
        for key,val in kwargs.items():#(('name',str),('age',int))
            setattr(obj,key,Typed(key,val))
        return obj
    return wrapper
@deco(name=str,age=int)  #@wrapper ===>People=wrapper(People)
class People:
    name='alex'
    def __init__(self,name,age,salary,gender,heigth):
        self.name=name
        self.age=age
        self.salary=salary
print(People.__dict__)

p = People('tiger',12,221,'nan','21')
'''
{'__module__': '__main__', 'name': <__main__.Typed object at 0x0000024B9C5B86A0>, '__init__': <function People.__init__ at 0x0000024B9C44CB70>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None, 'age': <__main__.Typed object at 0x0000024B9C5B8710>}
set方法
set方法
'''

通过描述符实现property功能

class Lazyproperty:
    def __init__(self,func):
        self.func = func
        # print("xxx")
    def __get__(self, instance, owner):     #不设置__set__函数,非数据描述符才能够实现缓存效果
        # print(instance)
        # print(owner)
        if instance == None: #类自己调用
            return self.func
        else:
            res = self.func(instance)
            print('get exec')
            setattr(instance,self.func.__name__,res)  #将area的值设置成为area函数的属性
            return res



class Room:
    def __init__(self,length,width):
        self.length = length
        self.width = width

    # @property
    @Lazyproperty
    def area(self):
        return self.length * self.width

r1 = Room(2,12)
print(r1.area)
print(Room.area)
'''
get exec
24
<function Room.area at 0x000001FA68F86C80>
'''

原文地址:https://www.cnblogs.com/chrrydot/p/9824400.html