python数据描述符
描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一个,这也被称为描述符协议
__get__():调用一个属性时,触发
__set__():为一个属性赋值时,触发
__delete__():采用del删除属性时,触发
class Str: def __get__(self, instance, owner): print('Str调用') def __set__(self, instance, value): print('Str设置...') def __delete__(self, instance): print('Str删除...') class People: name=Str() def __init__(self,name,age): #name被Str类代理,age被Int类代理, self.name=name self.age=age
数据描述符,对象访问顺序 依次向下
类属性
数据描述符: __get__ __set__
实例属性
非数据描述符: 没有 __set__
找不到属性触发 __getattr__
描述符的应用
class Typed: def __init__(self,key,expected_type): self.key = key self.expected_type = expected_type def __set__(self, instance, value): if not isinstance(value,self.expected_type): raise AttributeError('%s 传入的类型不是%s' %(self.key,self.expected_type)) instance.__dict__['self.key'] = value def __get__(self, instance, owner): return instance.__dict__['self.key'] def __delete__(self, instance): print("__delete__") class People: name = Typed('name',str) age = Typed('age',int) def __init__(self,name,age,salary): self.name = name self.age = age self.salary = salary p1 = People('wwwwww',2,32) print(p1.__dict__) p1.name = 'eeeee' print(p1.__dict__) print(p1.name)
结果
{'self.key': 2, 'salary': 32} {'self.key': 'eeeee', 'salary': 32} eeeee
装饰器应用
class Typed: def __init__(self,key,expected_type): self.key = key self.expected_type = expected_type def __get__(self, instance, owner): print('get方法') 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方法') def deco(**kwargs): #kwargs={'name':str,'age':int} def wrapper(obj): for k ,v in kwargs.items(): setattr(obj,k,Typed(k,v)) #People.name = typed('name',str) return obj return wrapper
@deco(name=str,age=int,salary=float) class People: # name = Typed('name',str) # age = Typed('age',int) # salary = Typed('salary', float) def __init__(self,name,age,salary): self.name = name self.age = age self.salary = salary p = People('auh',18,12000.1) print(p.__dict__)
@property 自己实现
class demo: def __init__(self, func): self.func = func #print('==========>', func) #<function test.area at 0x000000000220A0D0> def __get__(self, instance, owner): res = self.func(instance) return res class test: def __init__(self,name,length,wide): self.name = name self.length = length self.wide = wide #@property @demo #area=demo(area) def area(self): return self.length*self.wide f = test('home',1,1) print(f.area)