社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python语法糖之描述符

Crossin的编程教室 • 3 年前 • 571 次点击  
入门教程、案例源码、学习资料、读者群

请访问: python666.cn

大家好,欢迎来到 Crossin的编程教室 !

在日常的编码中,我们可以并应当使用 Python 的描述符,来使代码更具有单一职责原则,也就是 SRP(Single Responsibility Principle)原则。如果你还没有用过描述符,那快来看看怎么用吧,不然就不好意思说自己懂 Python。

那么什么是描述符?

描述符是控制对象属性访问的一种方式。它的好处是,让我们把类中设置和检索属性的任务抽离出来,并将这一任务交给另一个只有一个目的的类,帮助我们遵循 SRP 原则,也让代码更 Pythonic。

让我给你举个例子。你们大多数人都会知道 @property 装饰器,它基本上与描述符的作用相同。现在,让我们编写一个验证汽车油箱容量的类:

在上面的代码示例中,定义了一个有油箱的汽车类,我们希望限制油箱的容量不能小于 0 或高于 60 升。

@fuel_amount.setter 对赋值做检查,如果小于 0 或大于 60,就会引发 ValueError。为了获取油箱的容量,我们使用 @property,从私有属性 _fuel_amount 返回。

这看起来简单,好像也没什么问题,不过你细品一下,就会发现当属性越来越多的时候,你会看到满天的 property 和一堆业务逻辑代码的 setter,最后就是一个非常臃肿的 Car 类,看到你想吐,这与 Python 的设计哲学简单优雅相去甚远。

幸运的是,Python 有描述符。

现在来看看下面使用了描述符的代码,是不是清爽了很多:

这里的类 SixtyLitresCapacity 就是一个描述符类,作用就是限制大小为 0 到 60,具体代码如下:

其实也很简单,一个类定义了一个 __get__ 和 __set__ 方法,就可以作为一个描述符类(还要注意参数列表)。

需要注意的是,只有为类属性设置描述符时才有效。如果将描述符用于实例属性,Python 会忽略它。

我们还可以做的更好,比如说将描述符类做得更加通用:

这里的描述符类 IsBetween 代码如下:

在 IsBetween 里,我们添加了一些新东西。

1、添加了__init__方法,以启用上下边界的初始化(min_value 和 max_value),这样,不仅可以有 60 升的油箱,还可以在油箱只剩下 5 升燃料时发出告警的功能。为了抛出不同的异常,将异常通过__init__方法的参数传进去。

2、添加了__set_name__(self, owner, name)方法。因为私有属性不一定是_fuel_amount,可以是你喜欢的任何属性。这种个方法打开了将属性名传递给给描述符类的大门。没有这个方法,描述符将无法从类中获得任何信息。

可以看到,IsBetween 这个描述符类更加通用,可以描述诸如电池电量、年龄属性、温度等属性。

你看,描述符类是不是非常有用?同时也帮助我们的代码遵循 SRP。

作者:somenzz
来源:Python七号



Crossin的第2本书《码上行动:利用Python与ChatGPT高效搞定Excel数据分析》已经上市了。

点此查看上一本《码上行动:零基础学会Python编程》介绍

本书从 Python 和 Excel 结合使用的角度讲解处理分析数据的思路、方法与实战应用。不论是希望从事数据分析岗位的学习者,还是其他职业的办公人员,都可以通过本书的学习掌握 Python 分析数据的技能。书中创新性地将 ChatGPT 引入到教学当中,用 ChatGPT 答疑并提供实训代码,并介绍了使用 ChatGPT 辅助学习的一些实用技巧,给学习者带来全新的学习方式。


公众号的读者朋友们购买后可在后台联系我,加入读者交流群,Crossin会为你开启陪读模式,解答你在阅读本书时的一切疑问。


感谢转发和点赞的各位~

_往期文章推荐_

适合新手刷题的5个网站




如需了解付费精品课程及教学答疑服务
请在Crossin的编程教室内回复: 666
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/160900