返回介绍

9.10 本章小结

发布于 2024-02-05 21:59:47 字数 1405 浏览 0 评论 0 收藏 0

本章的目的是说明,如何使用特殊方法和约定的结构,定义行为良好且符合 Python 风格的类。

vector2d_v3.py(示例 9-9)比 vector2d_v0.py(示例 9-2)更符合 Python 风格吗? vector2d_v3.py 中的 Vector2d 类用到的 Python 功能肯定要多,但是 Vector2d 类的第一版和最后一版相比哪个更符合风格,要看使用的上下文。Tim Peter 写的“Python 之禅”说道:

简洁胜于复杂。

符合 Python 风格的对象应该正好符合所需,而不是堆砌语言特性。

我不断改写 Vector2d 类是为了提供上下文,以便讨论 Python 的特殊方法和编程约定。回看表 1-1,你会发现本章的几个代码清单说明了下述特殊方法。

所有用于获取字符串和字节序列表示形式的方法:__repr__、__str__、__format__ 和 __bytes__。

把对象转换成数字的几个方法:__abs__、__bool__和 __hash__。

用于测试字节序列转换和支持散列(连同 __hash__ 方法)的 __eq__ 运算符。

为了转换成字节序列,我们还实现了一个备选构造方法,即 Vector2d.frombytes(),顺便又讨论了 @classmethod(十分有用)和 @staticmethod(不太有用,使用模块层函数更简单)两个装饰器。frombytes 方法的实现方式借鉴了 array.array 类中的同名方法。

我们了解到,格式规范微语言是可扩展的,方法是实现 __format__ 方法,对提供给内置函数 format(obj, format_spec) 的 format_spec,或者提供给 str.format 方法的 '{:«format_spec»}' 位于代换字段中的 «format_spec» 做简单的解析。

为了把 Vector2d 实例变成可散列的,我们先让它们不可变,至少要把 x 和 y 设为私有属性,再以只读特性公开,以防意外修改它们。随后,我们实现了 __hash__ 方法,使用推荐的异或运算符计算实例属性的散列值。

接着,我们讨论了如何使用 __slots__ 属性节省内存,以及这么做要注意的问题。__slots__ 属性有点棘手,因此仅当处理特别多的实例(数百万个,而不是几千个)时才建议使用。

最后,我们说明了如何通过访问实例属性(如 self.typecode)覆盖类属性。我们先创建一个实例属性,然后创建子类,在类中覆盖类属性。

本章多次提到,我编写代码的方式是为了举例说明如何编写标准 Python 对象的 API。如果用一句话总结本章的内容,那就是:

要构建符合 Python 风格的对象,就要观察真正的 Python 对象的行为。

——古老的中国谚语

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文