前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >不用描述符,不算懂 Python

不用描述符,不算懂 Python

作者头像
somenzz
发布2022-02-15 14:56:25
4130
发布2022-02-15 14:56:25
举报
文章被收录于专栏:Python七号

在日常的编码中,我们应该使用 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。

最后的话

本文分享了 Python 中描述符的使用,有没有学到新技能呢?

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-01-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python七号 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 最后的话
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档