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