深入理解Python之继承
继承内置类型的技巧
Python2.2
之前,不能够继承内置类型
1 |
|
DoppelDict
当排序时,复制值.__init__
忽略__setitem__
被重写,因此one
没有被复制。[]
操作符调用__setitem__
,因此two
被复制。update
方法没有使用重写的__setitem__
方法。因此three
没有复制
方法的寻找总是从目标对象开始,然后向上寻找
1 | class AnswerDict(dict): |
AnswerDict.__getitem__()
总是返回42.d
是个dict
,使用ad
更新它,忽略了AnswerDict.__getitem__()
直接继承内置类型如dict
或者list
容易出错,因为内置的方法大多数会忽略用户自定的方法。因此从collections
模块中使用UserDict
,UserLisat
,UserString
来派生类
1 | class DoppelDict2(collections.UserDict): |
多继承
1 |
|
当在一个类上直接调用方法时,需要显式传入self
。调用方法的顺序依据MRO(__mro__)
采用C3
算法
1 |
|
其搜索路径就是按着Text, Widget, BaseWidget, Misc, Pack, Place, Grid, XView, YView, object
从左往右搜索
对于多重继承来说,继承顺序决定了搜索顺序
真实的多重继承案例
适配器模式就使用了多重继承.Python
中最常见的多重继承是collection.abc
包。标准库Tkinter GUI
使用了大量的多重继承
1 | print_mro(tkinter.Toplevel) |
应对多重继承
区分接口继承和实现继承
- 接口继承创建子类型,实现
is-a
关系 - 实现继承利于代码复用
- 接口继承创建子类型,实现
使用
ABCs
来创造接口使用
Mixin
来使代码复用如果一个类被设计成为多个不相关的类提供复用,那么请继承
Mixin
,Mixin
不会定义新类型,只是封装方法以便复用.Mixin
不该被实例化,任何实体类都不该仅仅只继承Mixin
. 每个Mixin
应该只提供一种单一特定的行为,实现几个紧密相关的方法显式命名
Mixin
没有标准的方式来说明一个类是
Mixin
,因此建议使用Mixin
作为后缀ABC
可能是Mixin
,反过来不一定成立不要继承多个实体类
提供集合类给用户
组合胜过继承