我的编程空间,编程开发者的网络收藏夹
学习永远不晚

流畅的python读书笔记-第十章-继

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

流畅的python读书笔记-第十章-继

推出继承的初衷是让新手顺利使用只有专家才能设计出来的框架。
——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 模块的类

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

流畅的python读书笔记-第十章-继

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

流畅的python读书笔记-第十章-继

推出继承的初衷是让新手顺利使用只有专家才能设计出来的框架。——Alan Kay子类化内置类型很麻烦 (如 list 或 dict)) ,别搞这种直接子类化内置类型(如 dict、list 或 str)容易出错,因为内置类型的 方法通常会忽略
2023-01-31

读书笔记之《编程小白的第1本Python

本书电子版下载地址:百度网盘写在前面:你需要这本书的原因有没有那一个瞬间,让你想要放弃学习编程?在我决心开始学编程的时候,我为自己制定了一个每天编程1小时的计划,那时候工作很忙,我只能等到晚上9点,同事都下班之后,独自留在办公室编程。做任何
2023-01-31

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录