基于描述符建立数据模型实现赋值验证框架
在实例属性的获取和设定方面,前面已经提过可以使用property和描述符实现
1、创建数据模型的基础构建模块
1 class Descriptor: 2 def __init__(self, name=None, **opts): 3 self.name = name 4 for key, val in opts.items(): 5 setattr(self, key, val) 6 7 def __set__(self, instance, value): 8 instance.__dict__[self.name] = value 9 10 11 class Typed(Descriptor): 12 expected_type = type(None) 13 14 def __set__(self, instance, value): 15 if not isinstance(value, self.expected_type): 16 raise TypeError("expect:{}".format(self.expected_type)) 17 super().__set__(instance, value) 18 19 20 class Unsigned(Descriptor): 21 def __set__(self, instance, value): 22 if value < 0: 23 raise ValueError("expect > 0") 24 super().__set__(instance, value)
接着
2、定义不同的数据类型
1 class Interger(Typed): 2 expected_type = int 3 4 5 class Float(Typed): 6 expected_type = float 7 8 9 class String(Typed): 10 expected_type = str
接着
3、介入类装饰器
1 def check_attributes(**kwargs): 2 def decorate(cls): 3 for key, value in kwargs.items(): 4 if isinstance(value, Descriptor): 5 value.name = key 6 setattr(cls, key, value) 7 else: 8 setattr(cls, key, value(key)) 9 return cls 10 11 return decorate
最后
4、应用
1 @check_attributes( 2 name=String, 3 age=Interger 4 ) 5 class Valley: 6 7 def __init__(self): 8 self.name = "g" 9 self.age = 26 10 11 12 if __name__ == '__main__': 13 print(Valley().__dict__)
整合
1 class Descriptor: 2 def __init__(self, name=None, **opts): 3 self.name = name 4 for key, val in opts.items(): 5 setattr(self, key, val) 6 7 def __set__(self, instance, value): 8 instance.__dict__[self.name] = value 9 10 11 class Typed(Descriptor): 12 expected_type = type(None) 13 14 def __set__(self, instance, value): 15 if not isinstance(value, self.expected_type): 16 raise TypeError("expect:{}".format(self.expected_type)) 17 super().__set__(instance, value) 18 19 20 class Unsigned(Descriptor): 21 def __set__(self, instance, value): 22 if value < 0: 23 raise ValueError("expect > 0") 24 super().__set__(instance, value) 25 26 27 class Interger(Typed): 28 expected_type = int 29 30 31 class Float(Typed): 32 expected_type = float 33 34 35 class String(Typed): 36 expected_type = str 37 38 39 def check_attributes(**kwargs): 40 def decorate(cls): 41 for key, value in kwargs.items(): 42 if isinstance(value, Descriptor): 43 value.name = key 44 setattr(cls, key, value) 45 else: 46 setattr(cls, key, value(key)) 47 return cls 48 49 return decorate 50 51 52 @check_attributes( 53 name=String, 54 age=Interger 55 ) 56 class Valley: 57 58 def __init__(self): 59 self.name = "g" 60 self.age = 26 61 62 63 if __name__ == '__main__': 64 print(Valley().__dict__)
这一块还是要好好琢磨琢磨