zoukankan      html  css  js  c++  java
  • Python随心记--描述符应用:检测类型

    class Open:
        def __init__(self,name):
            self.name = name
    
        def __enter__(self):
            pass
        def __exit__(self, exc_type, exc_val, exc_tb):    
            pass
            return True   #如果返回True 程序运行过程中发生异常也会被吞掉
    with Open('a.txt') as f:   #f是一个对象  触发__enter__
        print(f.name)   #如果这里发生异常,则也会触发__exit__
        print('=====》')   #这里执行后会触发__exit__
    描述符应用:检测类型
    至少实现__get__、__set__、__delete__中的一个方法
    class Typed:
        def __init__(self,key,expected_type):
            self.key = key
            self.expected_type = expected_type
        def __get__(self, instance, owner):
            return isinstance.__dict__[self.key]
        def __set__(self, instance, value):   #instance代表被代理的字典,这里就是People的字典
            if not isinstance(value,self.expected_type):
                raise TypeError('不是%s,类型错误喔' %self.expected_type)   #类型不对,抛出异常,终止程序
            instance.__dict__[self.key] = value
        def __delete__(self, instance):
            isinstance.__dict__.pop(self.key)
    
    class People:
        name = Typed('name',str)   #属性name被Typed代理了(如果代理没生效,注意描述符的优先级)
        age = Typed('age',int)
        def __init__(self,name,age,salary):
            self.name = name
            self.age = age
            self.salary = salary
    
    # people = People(1111,23,100000)
    people = People('lin',23,100000)
    
    print(people.__dict__)

    类的装饰器的基本原理
    def Typed(**kwargs):
        def deco(obj):
            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)
    class Foo:
        pass
    
    f = Foo
    print(Foo.__dict__)
    类的装饰器的应用
    class Typed:
        def __init__(self,key,expected_type):
            self.key = key
            self.expected_type = expected_type
        def __get__(self, instance, owner):
            return isinstance.__dict__[self.key]
        def __set__(self, instance, value):   #instance代表被代理的字典,这里就是People的字典
            if not isinstance(value,self.expected_type):
                raise TypeError('不是%s,类型错误喔' %self.expected_type)   #类型不对,抛出异常,终止程序
            instance.__dict__[self.key] = value
        def __delete__(self, instance):
            isinstance.__dict__.pop(self.key)
    def deco(**kwargs):
        def wrapper(obj):
            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:
        def __init__(self,name,age,salary):
            self.name = name
            self.age = age
            self.salary = salary
    
    people = People('lin',23,10000.1)
    
    print(People.__dict__)
    自定制property
    class Lazyproperty:
        def __init__(self,func):
            self.func = func
        def __get__(self, instance, owner):
            return self.func(instance)
        def __set__(self, instance, value):
            pass
        def __delete__(self, instance):
            pass
    class Room:
        area = Lazyproperty('x')   #描述符
        def __init__(self,name,width,length):
            self.name = name
            self.width = width
            self.length = length
        # @property   #area = property(area) property:
        @Lazyproperty   #area = Lazyproperty(area)
        def area(self):
            return self.width * self.length
    
    room = Room('卧室',10,10)
    
    print(room.area)   #实例调用
    print(Room.area)   #类调用
    自定制property实现延迟计算功能
    class Lazyproperty:
        def __init__(self,func):
            self.func = func
        def __get__(self, instance, owner):
            if instance is None:
                return self
            res = self.func(instance)
            setattr(instance,self.func.__name__,res)   #实现缓存效果 把结果存起来,下次直接取缓存的
            return res
        def __set__(self, instance, value):
            pass
        def __delete__(self, instance):
            pass
    class Room:
        area = Lazyproperty('x')   #描述符
        def __init__(self,name,width,length):
            self.name = name
            self.width = width
            self.length = length
        # @property   #area = property(area) property:
        @Lazyproperty   #area = Lazyproperty(area)
        def area(self):
            return self.width * self.length
    
    room = Room('卧室',10,10)
    
    print(room.area)   #实例调用
    自定制property 补充
    class ClassMethod:
        def __init__(self,func):
            self.func = func
        def __get__(self, instance, owner):
            def feedback(*args,**kwargs):
                # print('在这里可以加功能........')
                return self.func(owner,*args,**kwargs)
            return feedback
    
    class People:
        name = 'lin'
        @ClassMethod
        def say_hi(self,msg):
            print('你好啊 %s %s' %(self.name,msg))
    
    People.say_hi('你是谁')
    people = People()
    people.say_hi('你是谁')
    class Foo:
        @property
        def test(self):
            print('get的时候运行了喔')
        @test.setter
        def test(self,val):
            print('set设置参数',val)
        @test.deleter
        def test(self):
            print('delete的时候运行了喔')
    
    f = Foo()
    f.test
    f.test = 1
    class Foo:
        def get_test(self):
            print('get的时候运行了喔')
    
        def set_test(self, val):
            print('set设置参数', val)
    
        def del_test(self):
            print('delete的时候运行了喔')
    
        test = property(get_test, set_test, del_test)
    
    
    f = Foo()
    f.test
    f.test = 1
    class Goods:
        def __init__(self):
            self.original_proice = 100
            self.discount = 0.8
    
        @property
        def price(self):
            new_price = self.original_proice * self.discount
            return new_price
    
        @price.setter
        def price(self,value):
            self.original_proice = value
    
        @price.deleter
        def price(self):
            del self.original_proice
    
    goods = Goods()
    print(goods.price)
    goods.price = 200
    print(goods.price)
    元类介绍:类的类
    class Foo:
        pass
    FFo = type('FFo',(object,),{'x':1,'__init__':'__init__'})
    
    print(Foo)
    print(FFo)
    print(FFo.__dict__)
    自定义元类
    class MyType(type):
        def __init__(self,a,b,c):
            print('元类的构造函数')
        def __call__(self, *args, **kwargs):
            print('============》')
            print(self)
            print(args,kwargs)
            obj = object.__new__(self)   #object.__new__(Foo)  得到foo
            self.__init__(obj,*args,**kwargs)   #Foo.__init__()
            return obj
    class Foo(metaclass = MyType):   #Foo = MyType(Foo,'Foo',(),{})
        def __init__(self,name):
            self.name = name
    
    
    foo = Foo('lin')
    
    print(foo)
    print(foo.__dict__)
  • 相关阅读:
    [hihocoder-1974] 智能分包 状态压缩dp
    2018北京ICPC D. Frog and Portal 斐波那契数 构造
    [hdu-6621]K-th Closest Distance 主席树 线段树 2019 多校4
    [POJ 2104]K-th Number 主席树 可持久化线段树 入门
    [hdu-6623]Minimal Power of Prime
    [hdu-6608] Fansblog 威尔逊定理 质数的密度分布 2019 多校 3
    [codeforces1000F] One Occurrence
    [python] 机器学习 卷积神经网络 用迁移学习实现人脸识别
    [python] 安装TensorFlow问题 解决Cannot uninstall 'wrapt'. It is a distutils installed project
    浅谈getResource方法
  • 原文地址:https://www.cnblogs.com/Essaycode/p/10217380.html
Copyright © 2011-2022 走看看