例如,在某项目中,我们实现了一些类,并希望能像静态类型语言(C,C++,Java)那样对它们的实例属性做类型检查。
p = Person() p.name = 'Bob' #必须是str p.age = 18 #必须是int p.height = 1.83 #必须是float
要求:1. 可对实例属性指定类型;2. 赋予的类型不正确时抛出异常。
解决方案:
使用描述符来实现需要类型检查的属性:分别实现 __get__() 、 __set__() 、 __delete__() 方法,在 __set__() 内使用 isinstance() 函数做类型检查。
对于描述符:描述符就是一个“绑定行为”的对象属性,在描述符协议中,它可以通过方法充写属性的访问。这些方法有 __get__() 、 __set__() , __delete__() ,如果这些方法中任何一个被定义在一个对象中,这个对象就是一个描述符。
class Descriptor:
def __init__(self, key):
self.key = key
def __set__(self, instance, value):
instance.__dict__[self.key] = value #添加属性self.key:value到属性字典__dict__中
def __get__(self, instance, cls):
return instance.__dict__[self.key] #查询属性字典__dict__中键为self.key的值value
def __delete__(self, instance):
del instance.dict__[self.key] #删除属性字典__dict__中的键值对self.key:value
class A:
x = Descriptor('x')
y = Descriptor('y')a = A()a.x = 5a.y = 6上面的描述符类中, __set__() 特殊方法的参数有:
self 描述符类的实例 instance 相当于A类的实例a value:就是要赋予的值
__get__() 特殊方法的参数有:
self 描述符实例 instance 相当于A类的实例a cls 相当于A类
__delete__() 特殊方法的参数有:
self 描述符实例 instance 相当于A类的实例a解决方案:
class Attr:
def __init__(self, key, type_):
self.key = key
self.type_ = type_
def __set__(self, instance, value):
if not isinstance(value, self.type_):
raise TypeError('must be %s' % self.type_)
instance.__dict__[self.key] = value
def __get__(self, instance, cls):
return instance.__dict__[self.key]
def __delete__(self, instance):
del instance.dict__[self.key]class Person:
name = Attr('name', str)
age = Attr('age', int)
height = Attr('height', float)p = Person()p.name = 'Bob'p.age = 18p.height = 17Traceback (most recent call last): #结果
File "e:\Python practice\twenty-six\c5.py", line 27, in <module>
p.height = 17
File "e:\Python practice\twenty-six\c5.py", line 8, in __set__ raise TypeError('must be %s' % self.type_)TypeError: must be <class 'float'>可以看到最后的报错提示: TypeError: must be ,这就达成了使用描述符对实例属性做类型检查的目的。
查看更多关于35. 使用描述符对实例属性做类型检查的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did126741