描述符应用 -- 让python变成一个强类型的语言
众所周知,python是一门弱类型的语言,变量可以随意赋值成任意类型,但是通过描述符,我们可以把数据变成强类型的。
我们为数据设置数据描述符,因为数据描述的优先级大于实例属性,所以在给数据赋值的时候会优先出发数据描述符。
普通版
class Typed: def __init__(self, name, expected_type): self.name = name self.expected_type = expected_type def __get__(self, instance, owner): if instance is None: return self # 如果实例化用People.name调用的话,就返回Typed的实例name return instance.__dict__[self.name] def __set__(self, instance, value): if not isinstance(value, self.expected_type): raise TypeError('Type error') instance.__dict__[self.name] = value def __delete__(self, instance): instance.__dict__.pop(self.name) 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 # p1 = People(123, 18, 3333.3) # TypeError: Type error # p1=People('egon','18',3333.3) # TypeError: Type error # p1=People('egon',18,3333) # TypeError: Type error p1 = People('egon', 18, 3333.33) # 正确
用类的装饰器实现
先回顾一下setattr的语法
语法
setattr() 语法:
setattr(object, name, value)
参数
- object -- 对象。
- name -- 字符串,对象属性。
- value -- 属性值。
class Typed: def __init__(self, name, expected_type): self.name = name self.expected_type = expected_type def __get__(self, instance, owner): if instance is None: return self return instance.__dict__[self.name] def __set__(self, instance, value): if not isinstance(value, self.expected_type): raise TypeError('type error') instance.__dict__[self.name] = value def __delete__(self, instance): self.__dict__.pop(self.name) def typeassert(**kwargs): def decorator(cls): for name, expected_type in kwargs.items(): setattr(cls, name, Typed(name, expected_type)) return cls return decorator @typeassert(name=str, age=int, salary=float) class People: def __init__(self, name, age, salary): self.name = name self.age = age self.salary = salary p1 = People('edward', 18, 30000.00)