学习Python这么久了,说起Python的优雅之处,能让我脱口而出的,描述符(描述符)特性可以排得上号。
描述符是Python语言独有的特性,它不仅在应用层使用,在语言的基础设施中也有涉及。
我可以大胆地猜测,你对于描述符的了解是始于诸如Django ORM和SQLAlchemy中的字段对象,是的,它们都是描述符。你的它的认识,可能也止步于此,如果你没有去深究,它为何要如此设计?也就加体会不到Python给我们带来的便利与优雅。
由于描述符的内容较多,长篇大论,容易让你倦怠,所以我打算分几篇来讲。
今天的话题是:<强>为何要使用描述符? 强>
假想你正在给学校写一个成绩管理系统,并没有太多编码经验的你,可能会这样子写。
<代码类="语言python ">类学生: def __init__(自我、名称、数学、中文、英文): self.name=名字 自我。数学=数学 自我。中国=自我。英语=def __repr__(自我): 返回“& lt;学生:{},数学:{},中国人:{},中文:{}在“.format ( self.name,自我。数学,自我。中国人,self.english )代码>
看起来一切都很合理
<代码类="语言python ">在祝辞祝辞std1=学生(“小明”,76年,87年,68年) 在在在std1 & lt;学生:小明、数学:76年,中国:87年,英语:68年在代码>
但是程序并不像人那么智能,不会自动根据使用场景判断数据的合法性,如果老师在录入成绩的时候,不小心录入了将成绩录成了负数,或者超过100年,程序是无法感知的。
聪明的你,马上在代码中加入了判断逻辑。
<代码类="语言python ">类学生: def __init__(自我、名称、数学、中文、英文): self.name=名字 如果0 & lt;=数学& lt;=100: 自我。数学=数学 其他: 提高ValueError(“有效值必须在[0,100]”) 中国& lt;如果0 & lt;==100: 自我。中国=其他: 提高ValueError(“有效值必须在[0,100]”) 中国& lt;如果0 & lt;==100: 自我。英语=其他: 提高ValueError(“有效值必须在[0,100]”) def __repr__(自我): 返回“& lt;学生:{},数学:{},中国人:{},中文:{}在“.format ( self.name,自我。数学,自我。中国人,self.english )代码>
这下程序稍微有点人工智能了,能够自己明辨是非了。
程序是智能了,但在<代码> __init__> 代码里有太多的判断逻辑,很影响代码的可读性。巧的是,你刚好学过财产特性,可以很好的应用在这里。于是你将代码修改成如下,代码的可读性瞬间提升了不少
<代码类="语言python ">类学生: def __init__(自我、名称、数学、中文、英文): self.name=名字 自我。数学=数学 自我。中国=自我。英语=@ property def数学(自我): 返回self._math @math.setter def数学(自我价值): 如果0 & lt;=& lt;价值=100: 自我。_math=值 其他: 提高ValueError(“有效值必须在[0,100]”) @ property def中国(自我): 返回self._chinese @chinese.setter def中国(自我价值): 如果0 & lt;=& lt;价值=100: 自我。_chinese=值 其他: 提高ValueError(“有效值必须在[0,100]”) @ property def英语(自我): 返回self._english @english.setter def英语(自我价值): 如果0 & lt;=& lt;价值=100: 自我。_english=值 其他: 提高ValueError(“有效值必须在[0,100]”) def __repr__(自我): 返回“& lt;学生:{},数学:{},中国人:{},中文:{}在“.format ( self.name,自我。数学,自我。中国人,self.english )代码>
程序还是一样的人工智能,非常好。
你以为你写的代码,已经非常优秀,无懈可击了。
没想到,人外有天,小明看了你的代码后,深深地叹了口气:类里的三个属性,数学,中文,英语,都使用了财产对属性的合法性进行了有效控制。功能上,没有问题,但就是太啰嗦了,三个变量的合法性逻辑都是一样的,只要大于0,小于100年就可以,代码重复率太高了,这里三个成绩还好,但假设还有地理、生物,历史,化学等十几门的成绩呢,这代码简直没法忍。去了解一下Python的描述符吧。