浅析python继承与多重继承


Posted in Python onSeptember 13, 2018

记住以下几点:

直接子类化内置类型(如dict,list或str)容易出错,因为内置类型的方法通常会忽略用户覆盖的方法,不要子类化内置类型,用户自定义的类应该继承collections模块。

def __setitem__(self, key, value):
    super().__setitem__(key, [value] * 2) # 错误案例
class AnswerDict(dict):
  def __getitem__(self, item): # 错误案例
    return 42
import collections
class DoppelDict2(collections.UserDict): # 正确案例
  def __setitem__(self, key, value):
    super().__setitem__(key, [value] * 2)
class AnswerDict2(collections.UserDict): # 正确案例
  def __getitem__(self, item):
    return 42

多重继承有关的另一个问题就是:如果同级别的超类定义了同名属性.Python如何确定使用哪个?

class DoppelDict(dict):
  def __setitem__(self, key, value):
    super().__setitem__(key, [value] * 2)
class AnswerDict(dict):
  def __getitem__(self, item):
    return 42
import collections
class DoppelDict2(collections.UserDict):
  def __setitem__(self, key, value):
    super().__setitem__(key, [value] * 2)
class AnswerDict2(collections.UserDict):
  def __getitem__(self, item):
    return 42
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)
if __name__ == '__main__':
  d = D()
  print(d.pong()) # 输出来源于B
  print(C.pong(d)) #输出来源于C 超类的方法都可以直接调用,此时要把实例作为显示参数传入.

python能区别调用的是哪个方法,通过方法解析顺序

>>> D.mro()

[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

若想把方法调用委托给超类,推荐的方式是使用内置的super()函数.

以下是对于d.pingpong()方法的解读

>>> self.ping()

Ping: <__main__.D object at 0x000002213877F2B0> post-ping: <__main__.D object at 0x000002213877F2B0> 第一个调用的是self.ping(),运行的是是D类的ping,方法.

第二个调用的的是super().ping(),跳过D类的ping方法,找到A类的ping方法.Ping: <__main__.D object at 0x000002213877F2B0>

第三个调用的是self.pong()方法,根据__mro__,找到B类实现的pong方法. pong: <__main__.D object at 0x000002213877F2B0>

第四个调用时super().pong(),也是根据__mro__,找到B类实现的pong方法. pong: <__main__.D object at 0x000002213877F2B0>

第五个调用的是C.pong(self),忽略了__mro__,找到的是C类实现的pong方法. PONG: <__main__.D object at 0x000002213877F2B0>

Python 相关文章推荐
编程语言Python的发展史
Sep 26 Python
用Python进行基础的函数式编程的教程
Mar 31 Python
在Python中使用poplib模块收取邮件的教程
Apr 29 Python
python正则表达式的使用
Jun 12 Python
python基于ID3思想的决策树
Jan 03 Python
Python动态语言与鸭子类型详解
Jul 01 Python
pyqt5 QScrollArea设置在自定义侧(任何位置)
Sep 25 Python
Python3并发写文件与Python对比
Nov 20 Python
Python While循环语句实例演示及原理解析
Jan 03 Python
你可能不知道的Python 技巧小结
Jan 29 Python
python GUI库图形界面开发之PyQt5布局控件QGridLayout详细使用方法与实例
Mar 06 Python
python脚本使用阿里云slb对恶意攻击进行封堵的实现
Feb 04 Python
Python中分支语句与循环语句实例详解
Sep 13 #Python
Python爬虫小技巧之伪造随机的User-Agent
Sep 13 #Python
Python爬虫基础之XPath语法与lxml库的用法详解
Sep 13 #Python
Python爬虫常用小技巧之设置代理IP
Sep 13 #Python
python集合比较(交集,并集,差集)方法详解
Sep 13 #Python
python中dict字典的查询键值对 遍历 排序 创建 访问 更新 删除基础操作方法
Sep 13 #Python
Python字典创建 遍历 添加等实用基础操作技巧
Sep 13 #Python
You might like
优化php效率,提高php性能的一些方法
2011/03/24 PHP
PHP缓存技术的多种方法小结
2012/08/14 PHP
php遍历目录与文件夹的多种方法详解
2013/11/14 PHP
WordPress分页伪静态加html后缀
2016/06/08 PHP
php中mkdir()函数的权限问题分析
2016/09/24 PHP
PHP封装请求类实例分析【基于Yii框架】
2019/10/17 PHP
JavaScript中的面向对象介绍
2012/06/30 Javascript
css+js实现部分区域高亮可编辑遮罩层
2014/03/04 Javascript
当滚动条滚动到页面底部自动加载增加内容的js代码
2014/05/13 Javascript
jquery中val()方法是从最后一个选项往前读取的
2015/09/06 Javascript
详解Bootstrap按钮
2016/01/04 Javascript
JavaScript基于原型链的继承
2016/06/22 Javascript
Bootstrap CSS组件之面包屑导航(breadcrumb)
2016/12/17 Javascript
ajax图片上传,图片异步上传,更新实例
2016/12/30 Javascript
JS实现的集合去重,交集,并集,差集功能示例
2018/03/13 Javascript
angular2实现统一的http请求头方法
2018/08/13 Javascript
快速解决Vue项目在IE浏览器中显示空白的问题
2018/09/04 Javascript
jQuery扩展方法实现Form表单与Json互相转换的实例代码
2018/09/05 jQuery
JS+Canvas实现五子棋游戏
2020/08/26 Javascript
Python标准库urllib2的一些使用细节总结
2015/03/16 Python
使用CodeMirror实现Python3在线编辑器的示例代码
2019/01/14 Python
在Python中过滤Windows文件名中的非法字符方法
2019/06/10 Python
python动态视频下载器的实现方法
2019/09/16 Python
python实现替换word中的关键文字(使用通配符)
2020/02/13 Python
Python如何定义有默认参数的函数
2020/08/10 Python
手把手教你用Django执行原生SQL的方法
2021/02/18 Python
UNOde50美国官网:西班牙珠宝品牌
2020/08/15 全球购物
网上常见的一份Linux面试题(多项选择部分)
2014/09/09 面试题
nohup的用法
2014/08/10 面试题
HttpServlet类中的主要方法都有哪些?各自的作用是什么?
2014/03/16 面试题
室内设计实习自我鉴定
2013/09/25 职场文书
开业主持词
2014/03/21 职场文书
考试作弊检讨书
2015/01/27 职场文书
应届生简历自我评价
2015/03/11 职场文书
婚礼领导致辞大全
2015/07/28 职场文书
优化经济发展环境工作总结
2015/08/11 职场文书