类的装饰器

def deco(func):
    print('======')
    return func

@deco           #--->test=deco(test)
def test():
    print('test----')

test()

#result
# ======
# test----


@deco               #------>Foo=deco(Foo)
class Foo:
    pass
#======
基本原理
def deco(obj):
    obj.x=1
    obj.y=2
    obj.z=3
    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, 'z': 3}
View Code

 

def Typed(**kwargs):
    def deco(obj):
        print('--->',kwargs)
        for key,val in kwargs.items():
            # obj.__dict__[key]=val         #报错:不支持这种方式
            setattr(obj,key,val)
        return obj
    return deco

@Typed(x=1,y=2,z=3)       #1.Typed(x=1,y=2,z=3)--->deco  2.@deco--->Foo=deco(Foo)
class Foo:
    pass
print(Foo.__dict__)
#result:
# ---> {'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}

@Typed(name='alex')         #---> {'name': 'alex'}
class Bar:
    pass
print(Bar.name)             #alex
高阶函数嵌套可以给不同的类加上各自的属性

 

class Typed:
    def __init__(self,key,expected_type):
        self.key=key
        self.expected_type=expected_type

    def __get__(self, instance, owner):
        print('get方法',instance,owner,sep='----')

    def __set__(self, instance, value):
        print('set方法',instance,value,sep='----')
        # instance.__dict__['name']=value     #写死了
        if not isinstance(value,self.expected_type):
             raise TypeError('输入类型不是%s'%self.expected_type)
        instance.__dict__[self.key]=value

    def __delete__(self, instance):
        print('delete方法',instance)
        instance.__dict__.pop(self.key)

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

@deco(name=str,age=int,salary=float)
class People:
    # name=Typed('name',str)
    # age=Typed('age',int)
    # salary=Typed('salary',float)
    def __init__(self,name,age,salary):
        self.name=name
        self.age=age
        self.salary=salary


p1=People('alex',18,66.6)           #set方法
类装饰器的应用

 

posted @ 2019-03-31 21:43  wind_y  阅读(84)  评论(0编辑  收藏  举报