返回介绍

20.7 延伸阅读

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

除了语言参考手册中必读的“Data model”一章,Raymond Hettinger 写的“Descriptor HowTo Guide”也值得一读——这是 Python 官方文档 HowTo 合集中的一篇。

对 Python 对象模型相关的话题来说,Alex Martelli 写的《Python 技术手册(第 2 版)》一书虽然有点过时,但仍然提供了权威且客观的论述:本章讨论的关键机制在 Python 2.2 中引入,远在那本书涵盖的 2.5 版之前。Martelli 还做了一次题为“Python's Object Model”的演讲,深入探讨了特性和描述符 [ 幻灯片视频],强烈推荐观看。

至于针对 Python 3 的实例,David Beazley 与 Brian K. Jones 的《Python Cookbook(第 3 版)中文版》一书中有很多说明描述符的诀窍,推荐阅读的有“6.12 读取嵌套型和大小可变的二进制结构”“8.10 让属性具有惰性求值的能力”“8.13 实现一种数据模型或类型系统”和“9.9 把装饰器定义成类”。最后一个诀窍解决了函数装饰器、描述符和方法之间相互作用的深层次问题,说明了如何使用有 __call__ 方法的类实现函数装饰器;如果既想装饰方法又想装饰函数,还要实现 __get__ 方法。

杂谈

self 的问题

“变糟更好”(“Worse is Better”)是Richard P. Gabriel 在“The Rise of Worse is Better”一文中提出的设计思想。这个思想的第一要义是“简单”;对此,Gabriel 说道:

设计方式必须简单,对实现和接口来说都应如此。简单的实现比简单的接口更重要。简单是设计过程中最重要的考虑因素。

我认为,Python 要求明确把方法的第一个参数声明为 self 是“变糟更好”思想的体现。这样,实现是简单了(甚至也优雅了),但却牺牲了用户接口:方法的签名——例如 def zfill(self, width):——在外观上与 pobox.zfill(8) 调用不匹配。

这种做法(以及使用 self 这个标识符)由 Modula-3 语言创造,但是与 Python 有差异:在 Modula-3 中,接口的声明与实现是分开的,而且在接口声明中会省略 self 参数,因此对用户来说,接口声明中的方法显示的参数数量与真正接受的参数数量完全一致。

在这方面,Python 有一项改进——错误消息。对于用户定义的单参数(除 self 之外)方法来说,如果用户调用 obj.meth(),Python 2.7 会抛出异常,显示 TypeError: meth() takes exactly 2 arguments (1 given);不过在 Python 3.4 中,错误消息没那么难以理解了,解决了参数数量问题,还指出了缺失的参数:meth() missing 1 required positional argument: 'x'。

除了要明确把 self 作为参数之外,限制必须使用 self 访问实例属性也备受批评。8 我自己并不介意输入 self 限定符,这样便于把局部变量和属性区分开。我介意的是在 def 语句中使用 self。但是我已经习惯了。

如果讨厌 Python 要求显式使用 self,可以想想 JavaScript 中隐式的 this 那变幻莫测的语义,这样感觉就会好多了。像这样使用self 有一些合理之处,Guido 在他的博客 The History of Python 中写了一篇文章,题为“Adding Support for User-defined Classes”,说明了这些原因。

8例如,A. M. Kuchling 发表的著名文章“Python Warts”(存档)。Kuchling 自己并不讨厌 self 限定符,但是他提到了这一点——可能是为了呼应 comp.lang.python 邮件列表中的观点。

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

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

发布评论

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