7-6 如何使用描述符对实例属性做类型检查

一、描述符包含__get__、__set__或__delete__三个方法中的一个就是描述符。类似于7-4中的property类,内部也是实现了这三个方法。
class Descriptor(object): def __get__(self,instance,cls): print('in __get__ ',instance,cls ) def __set__(self,instace,cls): print('in __set__ ',instance,cls ) def __delete__(self,instace,cls): print('in __delete__ ',instance,cls ) #在另一个类中定义一个类的属性是描述符的实例时,A这个的一个实例a对这个属性x进行操作时,会被描述符里的结果所截获 class A(object): x = Descriptor() a = A() a.x #用实例a调用属性,instance传入的是类A,实际上现在x不是a的属性,返回的是instance的__dict__[]字典的元素 A.x #直接用类调用属性,instance传入的是none print(a.__dict__)
结果输出:
('in __get__ ', <__main__.A object at 0x02727A90>, <class '__main__.A'>) ('in __get__ ', None, <class '__main__.A'>) {} #输出结果为空,说明x不是a的属性
二、使x成为a的属性
class Descriptor(object): def __get__(self,instance,cls): print('in __get__ ',instance,cls ) return instance.__dict__['x'] def __set__(self,instance,value): print('in __set__ ' ) instance.__dict__['x'] = value #用动态绑定属性添加到类中 def __delete__(self,instance): print('in __delete__ ',instance ) class A(object): x = Descriptor() a = A() a.x = 5 #注意必须要先赋值才能使用。类似于定义对象时要先赋值是同理 #A.x print(a.__dict__)
输出结果:
in __set__ {'x': 5}
三、一个判断属性类型的例子
class Attr(object): def __init__(self,name,type_): self.name = name; self.type_ = type_ def __get__(self,instance,cls): #print('in __get__ ',instance,cls ) return instance.__dict__[self.name] def __set__(self,instance,value): if not isinstance(value,self.type_): #使用isinstance()判断类型 raise TypeError("except a %s" %self.type_) #print('in __set__ ' ) instance.__dict__[self.name] = value def __delete__(self,instance): #print('in __delete__ ',instance ) del instance.__dict__[self.name] class Person(object): name = Attr('name',str) age = Attr('age',int) height = Attr('height',float) lilei = Person() lilei.name = 'lilei' lilei.age = 18 lilei.height = 1.80 print(lilei.name,lilei.age,lilei.height)
结果输出:
('lilei', 18, 1.8)
zhang = Person() #zhang.name = 89 zhang.age = "zhangliang" 输出结果: Traceback (most recent call last): File "C:/视频/python高效实践技巧笔记/7类与对象相关话题/descriptor7-6.py", line 39, in <module> zhang.age = "zhangliang" File "C:/视频/python高效实践技巧笔记/7类与对象相关话题/descriptor7-6.py", line 13, in __set__ raise TypeError("except a %s" %self.type_) TypeError: except a <type 'int'>
posted on 2018-05-08 15:30 石中玉smulngy 阅读(175) 评论(0) 收藏 举报
浙公网安备 33010602011771号