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__)

 

posted @ 2019-01-03 22:43  爱跑步的乌龟  阅读(172)  评论(0编辑  收藏  举报