程序2:混入类/描述符
1 class Descriptor: 2 def __init__(self, name=None, **opts): 3 self.name = name 4 for key, value in opts.items(): 5 setattr(self, key, value) 6 7 def __set__(self, instance, value): 8 instance.__dict__[self.name] = value 9 10 11 # Descriptor for enforcing types 12 class Typed(Descriptor): 13 expected_type = type(None) 14 15 def __set__(self, instance, value): 16 if not isinstance(value, self.expected_type): 17 raise TypeError('expected ' + str(self.expected_type)) 18 super().__set__(instance, value) 19 20 21 # Descriptor for enforcing values 22 class Unsigned(Descriptor): 23 def __set__(self, instance, value): 24 if value < 0: 25 raise ValueError('Expected >= 0') 26 super().__set__(instance, value) 27 28 29 class MaxSized(Descriptor): 30 def __init__(self, name=None, **opts): 31 if 'size' not in opts: 32 raise TypeError('missing size option') 33 super().__init__(name, **opts) 34 35 def __set__(self, instance, value): 36 if len(value) >= self.size: 37 raise ValueError('size must be < ' + str(self.size)) 38 super().__set__(instance, value) 39 40 class Integer(Typed): 41 expected_type = int # 将上面的赋值覆盖了 42 43 class UnsignedInteger(Integer, Unsigned): 44 pass 45 46 class Float(Typed): 47 expected_type = float 48 49 class UnsignedFloat(Float, Unsigned): 50 pass 51 52 class String(Typed): 53 expected_type = str 54 55 class SizedString(String, MaxSized): 56 pass 57 58 59 class Stock: 60 # Specify constraints 61 name = SizedString('name', size=8) 62 shares = UnsignedInteger('shares') 63 price = UnsignedFloat('price') 64 65 def __init__(self, name, shares, price): 66 self.name = name 67 self.shares = shares 68 self.price = price 69 70 s=Stock('sdf',23,4.3) 71 # s.shares = 2.3 72 s.shares=-10