- 前言
- 目标读者
- 非目标读者
- 本书的结构
- 以实践为基础
- 硬件
- 杂谈:个人的一点看法
- Python 术语表
- Python 版本表
- 排版约定
- 使用代码示例
- 第一部分 序幕
- 第 1 章 Python 数据模型
- 第二部分 数据结构
- 第 2 章 序列构成的数组
- 第 3 章 字典和集合
- 第 4 章 文本和字节序列
- 第三部分 把函数视作对象
- 第 5 章 一等函数
- 第 6 章 使用一等函数实现设计模式
- 第 7 章 函数装饰器和闭包
- 第四部分 面向对象惯用法
- 第 8 章 对象引用、可变性和垃圾回收
- 第 9 章 符合 Python 风格的对象
- 第 10 章 序列的修改、散列和切片
- 第 11 章 接口:从协议到抽象基类
- 第 12 章 继承的优缺点
- 第 13 章 正确重载运算符
- 第五部分 控制流程
- 第 14 章 可迭代的对象、迭代器和生成器
- 14.1 Sentence 类第1版:单词序列
- 14.2 可迭代的对象与迭代器的对比
- 14.3 Sentence 类第2版:典型的迭代器
- 14.4 Sentence 类第3版:生成器函数
- 14.5 Sentence 类第4版:惰性实现
- 14.6 Sentence 类第5版:生成器表达式
- 14.7 何时使用生成器表达式
- 14.8 另一个示例:等差数列生成器
- 14.9 标准库中的生成器函数
- 14.10 Python 3.3 中新出现的句法:yield from
- 14.11 可迭代的归约函数
- 14.12 深入分析 iter 函数
- 14.13 案例分析:在数据库转换工具中使用生成器
- 14.14 把生成器当成协程
- 14.15 本章小结
- 14.16 延伸阅读
- 第 15 章 上下文管理器和 else 块
- 第 16 章 协程
- 第 17 章 使用期物处理并发
- 第 18 章 使用 asyncio 包处理并发
- 第六部分 元编程
- 第 19 章 动态属性和特性
- 第 20 章 属性描述符
- 第 21 章 类元编程
- 结语
- 延伸阅读
- 附录 A 辅助脚本
- Python 术语表
- 作者简介
- 关于封面
12.6 本章小结
本章对继承的讨论先从子类化内置类型引起的问题谈起:内置类型的原生方法使用 C 语言实现,不会调用子类中覆盖的方法,不过有极少数例外。因此,需要定制 list、dict 或 str 类型时,子类化 UserList、UserDict 或 UserString 更简单。这些类在 collections 模块中定义,它们其实是对内置类型的包装,会把操作委托给内置类型——这是标准库中优先选择组合而不使用继承的三个例子。如果所需的行为与内置类型区别很大,或许更容易的做法是,子类化 collections.abc 模块中相应的抽象基类,然后自己实现。
本章余下的内容着重探讨了多重继承这把双刃剑。首先,我们说明了 __mro__ 类属性中蕴藏的方法解析顺序,有了这一机制,继承方法的名称不再会发生冲突。我们还提到,内置的 super() 函数会按照 __mro__ 属性给出的顺序调用超类的方法。然后,我们分析了 Python 标准库中 GUI 工具包 Tkinter 对多重继承的运用。Tkinter 不能代表当前的最佳实践,因此我们讨论了处理多重继承的一些方式,例如谨慎使用混入类,以及借助组合模式彻底避免使用多重继承。指出 Tkinter 对多重继承的使用已经到了滥用的程度后,我们在最后一节分析了 Django 基于类的视图,了解了它们的核心层次结构。我觉得这更好地利用了混入。
Lennart Regebro(一位经验非常丰富的 Python 程序员,也是本书的技术审校之一)发现 Django 通过混入设计的视图层次结构有点混乱。但是他又写道:
多重继承的危害和缺点被放大了。我从来不觉得它是什么大问题。
总之,每个人对如何使用以及要不要在自己的项目中使用多重继承都有自己的观点。但是,我们往往没得选择,因为我们必须使用的框架有它们自己的选择。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论