• 类的装饰器


    实现给类添加属性

    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>
    '''
    

  • 相关阅读:
    深入理解多态..............................
    走过路过 不要错过..
    进军C#..
    员工打卡....
    MySQL
    MySQL
    MySQL
    MySQL
    MySQL
    MySQL
  • 原文地址:https://www.cnblogs.com/chrrydot/p/9824400.html
Copyright © 2020-2023  润新知