zoukankan      html  css  js  c++  java
  • 类的装饰器

    实现给类添加属性

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

  • 相关阅读:
    进程池,线程池,协程,gevent模块,协程实现单线程服务端与多线程客户端通信,IO模型
    线程相关 GIL queue event 死锁与递归锁 信号量l
    生产者消费者模型 线程相关
    进程的开启方式 进程的join方法 进程间的内存隔离 其他相关方法 守护进程 互斥锁
    udp协议 及相关 利用tcp上传文件 socketserver服务
    socket套接字 tcp协议下的粘包处理
    常用模块的完善 random shutil shevle 三流 logging
    day 29 元类
    Django入门
    MySQL多表查询
  • 原文地址:https://www.cnblogs.com/chrrydot/p/9824400.html
Copyright © 2011-2022 走看看