继承的优缺点

推出继承的初衷是让新手顺利使用只有专家才能设计出来的框架。
——Alan Kay

子类化内置类型很麻烦 (如 list 或 dict)) ,别搞这种

  1. 直接子类化内置类型(如 dict、list 或 str)容易出错,因为内置类型的 方法通常会忽略用户覆盖的方法。
  2. 不要子类化内置类型,用户自己定义的类应该继承 collections 模块的类,
  3. 例如UserDict、UserList 和 UserString,这些类做了特殊设计,因此易于扩展。
import collections

class DoppelDict2(collections.UserDict):
def __setitem__(self, key, value):
super().__setitem__(key, [value] * 2) dd = DoppelDict2(one=1)
print(dd) dd['two'] = 2
print(dd) dd.update(three=3)
print(dd) class AnswerDict2(collections.UserDict):
def __getitem__(self, key):
return 42 ad = AnswerDict2(a='foo') print(ad["a"])
  • 综上,本节所述的问题只发生在 C 语言实现的内置类型内部的方法委托上,而且只影响 直接继承内置类型的用户自定义类。
  • 如果子类化使用 Python 编写的类,如 UserDict 或 MutableMapping,就不会受此影响。

多重继承和方法解析顺序

class A:
def ping(self):
print('ping:', self) class B(A):
def pong(self):
print('pong:', self) class C(A):
def pong(self):
print('PONG:', self) class D(B, C):
def ping(self):
super().ping()
print('post-ping:', self) def pingpong(self):
self.ping()
super().ping()
self.pong()
super().pong()
C.pong(self) d = D()
d.pong() C.pong(d) #看继承关系
print(D.__mro__)

直接调用 d.pong() 运行的是 B 类中的版本。

Python 能区分 d.pong() 调用的是哪个方法,是因为 Python 会按照特定的顺序遍历继承图。
这个顺序叫方法解析顺序(Method Resolution Order,MRO)。
类都有一个名为__mro__ 的属性,它的值是一个元组,按照方法解析顺序列出各个超类,从当前类一直向上,直到 object 类。D

然而,使用 super() 最安全,也不易过时。调用框架或不受自己控制的类层次结构中的
方法时,尤其适合使用 super()。

多重继承的真实应用

1 多重继承能发挥积极作用。
2 《设计模式:可复用面向对象软件的基础》一书中的适配器模式用的就是多重继承,因此使用多重继承肯定没有错
3(那本书中的其他 22 个设计模式都使用单继承,因此多重继承显然不是灵丹妙药)

处理多重继承

下面是避免把类图搅乱的一些建议。

01. 把接口继承和实现继承区分开

使用多重继承时,一定要明确一开始为什么创建子类。主要原因可能有:

继承接口,创建子类型,实现“是什么”关系
继承实现,通过重用避免代码重复

其实这两条经常同时出现,不过只要可能,一定要明确意图。通过继承重用代码是实
现细节,通常可以换用组合和委托模式。而接口继承则是框架的支柱。

02. 使用抽象基类显式表示接口

现代的 Python 中,如果类的作用是定义接口,应该明确把它定义为抽象基类。Python
3.4 及以上的版本中,我们要创建 abc.ABC 或其他抽象基类的子类

python没有interface这种定义

03. 通过混入重用代码

  • 一个类的作用是为多个不相关的子类提供方法实现
  • 应该把那个类明确地定义为混入类(mixin class)
  • 从概念上讲,混入不定义新类型,只是打包方法,便于重用。
  • 混入类绝对不能实例化,而且具体类不能只继承混入类。
  • 混入类应该提供某方面的特定行为,只实现少量关系非常紧密的方法。

04. 在名称中明确指明混入

  • 因为在 Python 中没有把类声明为混入的正规方式,所以强烈推荐在名称中加入...Mixin 后缀。
  • Tkinter 没有采纳这个建议,如果采纳的话,XView 会变成XViewMixin,Pack 会变成 PackMixin

05. 为用户提供聚合类

class Widget(BaseWidget, Pack, Place, Grid):
"""Internal class.
Base class for a widget which can be positioned with the
geometry managers Pack, Place or Grid."""
pass

Widget 类的定义体是空的,但是这个类提供了有用的服务:

把四个超类结合在一起,这样需要创建新小组件的用户无需记住全部混入,也不用担心声明 class 语句时有没有遵守特定的顺序。

08. “优先使用对象组合,而不是类继承”

这句话引自《设计模式:可复用面向对象软件的基础》一书, 这是我能提供的最佳
建议。

熟悉继承之后,就太容易过度使用它了。出于对秩序的诉求,我们喜欢按整洁
的层次结构放置物品,程序员更是乐此不疲。

即便是单继承,这个原则也能提升灵活性,因为子类化是
一种紧耦合,而且较高的继承树容易倒。

继承在Django的应用

page 417 这里有些复杂,等我牛掰了再来看

总结

collections.abc 模块中相应的抽象基类
多重继承这把双刃剑。首先,我们说明了 mro 类属性中蕴藏的方法解析顺序,有了这一机制,继承方法的名称不再会发生冲突
不要子类化内置类型,用户自己定义的类应该继承 collections 模块的类

流畅的python读书笔记-第十章-继承优缺点的更多相关文章

  1. 流畅的Python读书笔记(二)

    2.1 可变序列与不可变序列 可变序列 list. bytearray. array.array. collections.deque 和 memoryview. 不可变序列 tuple. str 和 ...

  2. 流畅的python 读书笔记 第二章 序列构成的数组 列表推导

    列表推导是构建列表(list)的快捷方式,而生成器表达式则可以用来创建其他任何类型的序列.如果你的代码里并不经常使用它们,那么很可能你错过了许多写出可读性更好且更高效的代码的机会. 2.2.1 列表推 ...

  3. Web Scraping with Python读书笔记及思考

    Web Scraping with Python读书笔记 标签(空格分隔): web scraping ,python 做数据抓取一定一定要明确:抓取\解析数据不是目的,目的是对数据的利用 一般的数据 ...

  4. Java Concurrency in Practice 读书笔记 第十章

    粗略看完<Java Concurrency in Practice>这部书,确实是多线程/并发编程的一本好书.里面对各种并发的技术解释得比较透彻,虽然是面向Java的,但很多概念在其他语言 ...

  5. 《利用python进行数据分析》读书笔记--第十章 时间序列(三)

    7.时间序列绘图 pandas时间序列的绘图功能在日期格式化方面比matplotlib原生的要好. #-*- coding:utf-8 -*- import numpy as np import pa ...

  6. python读书笔记-《A Byte of Python》中文第三版后半部分

    编辑器:windows,linux 不要用notepad,缩进糟糕 -------------- 5.18缩进 同一层次的语句必须有相同的缩进.每一组这样的语句称为一个块. i = 5 2  prin ...

  7. OK - A byte of python - 读书笔记

    看这本书的目的:再熟悉基本概念. 大部分都是知道,但是需要 明确 出来的 概念. - 欢迎吐槽错误,非常感谢. <A byte of python> - THIS 1. 组织行 - 形式: ...

  8. Python学习笔记8-类的继承 、深度优先、广度优先

    Python 类声明 语法: class 类名: 类体 例: #--encoding:utf-8-- # class AddressBookEntity: myVersion=0.1 def __in ...

  9. 【updating】python读书笔记-The Django Book2.0(for django1.4)

    原文:http://www.djangobook.com/en/2.0/frontmatter.html 译文:http://djangobook.py3k.cn/2.0/ 或者http://docs ...

随机推荐

  1. cephfs分布式系统

                                                               cephfs分布式系统 CephFS:分布式文件系统 l 什么是CephFS: 分 ...

  2. MySQL入门,第一部分,全局管理命令

    1.连接数据库命令 mysql -h localhost -u root -p 回车后输入密码即可连接到数据库 2.显示当前mysql管理系统中的所有数据库 SHOW DATABASES; 3.显示当 ...

  3. C语言 文件复制

    有很多人会问,学会C语言能干啥?,就只能控制台敲个数学题,做个界面都没有的贪吃蛇么? 刚开始的我,也是这样想的,但慢慢深入C语言后,我才领略到C的强大,C的万能.小到游戏破解,加解密算法,大到设备驱动 ...

  4. C++语言实现顺序栈

    C++语言实现顺序栈 在写C语言实现顺序栈的时候,我已经向大家介绍了栈的特点以及介绍了栈的相关操作,并利用C语言实现了相关算法.在这里小编就不在继续给大家介绍了,需要温习的可以去我的博客看看.在这篇博 ...

  5. Flutter 吐血整理组件继承关系图

    老孟导读:前几天一个读者和我说能不能整理一个各个控件之间的继承关系,这2天抽时间整理了一下,不整理不知道,一整理真的吓一跳啊,仅仅Widget的子类(包括间接子类)就高达353个,今天发群里给大家浏览 ...

  6. @suppressWarnings("unchecked") java 中是什么意思 (一般放dao查询方法上)

    J2SE 提供的最后一个批注是 @SuppressWarnings.该批注的作用是给编译器一条指令,告诉它对被批注的代码元素内部的某些警告保持静默. 一点背景:J2SE 5.0 为 Java 语言增加 ...

  7. 自己总结 :并发队列ConcurrentLinkedQueue、阻塞队列AraayBlockingQueue、阻塞队列LinkedBlockingQueue 区别 和 使用场景总结

    并发队列ConcurrentLinkedQueue.阻塞队列AraayBlockingQueue.阻塞队列LinkedBlockingQueue 区别 和  使用场景总结 分类: Java2013-0 ...

  8. 借助Python来实现的定量城市研究

    一.数据处理基础 (一)数据分析的概念 城市数据分析,可以从数据分析的广义和狭义两个角度来看: 狭义的数据分析是指根据分析目的,采用对比分析.分组分析.交叉分析和回归分析等分析方法,对相关城市数据(包 ...

  9. pandas basic cheatsheet

    "胖的要死"是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的.Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具. 有多大?这篇 ...

  10. vue中SPA的优缺点和理解

    说说你对SPA的理解,他的优缺点分别是什么? SPA(single-page application) 尽在Web页面初始化时加载相应的HTML,JavaScript和CSS.一旦页面加载完成,SPA ...