Python描述符

现在试想一下我们有一个这样的场景。

class Person: def __init__(self, name, gender): self.name = name self.gender = gender

我们希望在这里加入类型检查,name和gender都必须为字符串。
熟悉python的同学当然想到了property。那我们的代码就变成了这样子。
class Person: def __init__(self, name, gender): self.name = name self.gender = gender@property def name(self): return self._name@name.setter def name(self, name): if isinstance(name, str): self._name = name else: raise AttributeError('name must be a string !')@property def gender(self): return self._gender@gender.setter def gender(self, gender): if isinstance(gender, int): self._gender = gender else: raise AttributeError('gender must be a string !')

有没有发现一个很严重的问题,我们写了重复的逻辑,这样做是个十分不好的设计。我们希望自己写的类似于类型检查的逻辑可以复用。
下面就该我们描述符出场了,我们的代码变为了下面这样子。
class StringField: def __get__(self, instance, owner): return self.datadef __set__(self, instance, value): if not isinstance(value, str): raise ValueError('need string !') self.data = https://www.it610.com/article/valuedef __delete__(self): ...class Person: name = StringField() gender = StringField()if __name__ =='__main__': p = Person() p.name = 'Tom' print(p.name) p.name = 123

我们看一下输出结果。
Tom Traceback (most recent call last):File "/Users/shizhentao/PythonProjects/flask-demo/test.py", line 30, in p.name = 123File "/Users/shizhentao/PythonProjects/flask-demo/test.py", line 8, in __set__ raise ValueError('need string !') ValueError: need string !

【Python描述符】跟上面的代码实现的效果一样,但是我们实现的十分精简。

    推荐阅读