浅析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 09 Python
Tensorflow 自带可视化Tensorboard使用方法(附项目代码)
Feb 10 Python
Python-OpenCV基本操作方法详解
Apr 02 Python
详解Python如何生成词云的方法
Jun 01 Python
Python实现连接MySql数据库及增删改查操作详解
Apr 16 Python
python中使用ctypes调用so传参设置遇到的问题及解决方法
Jun 19 Python
Python占用的内存优化教程
Jul 28 Python
python深copy和浅copy区别对比解析
Dec 26 Python
Matplotlib scatter绘制散点图的方法实现
Jan 02 Python
python zip,lambda,map函数代码实例
Apr 04 Python
什么是python的必选参数
Jun 21 Python
如何利用python正则表达式匹配版本信息
Dec 09 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
下载文件的点击数回填
2006/10/09 PHP
PHP中for循环语句的几种变型
2006/11/26 PHP
隐藏X-Space个人空间下方版权方法隐藏X-Space个人空间标题隐藏X-Space个人空间管理版权方法
2007/02/22 PHP
php安装xdebug/php安装pear/phpunit详解步骤(图)
2013/12/22 PHP
用PHP代码在网页上生成图片
2015/07/01 PHP
Thinkphp框架使用list_to_tree 实现无限级分类列出所有节点示例
2020/04/04 PHP
javascript之可拖动的iframe效果代码
2008/08/01 Javascript
编写兼容IE和FireFox的脚本
2009/05/18 Javascript
JQuery select控件的相关操作实现代码
2012/09/14 Javascript
使用js 设置url参数
2013/07/08 Javascript
jQuery拖动div、移动div、弹出层实现原理及示例
2014/04/08 Javascript
JavaScript中输出标签的方法
2014/08/27 Javascript
微信WeixinJSBridge API使用实例
2015/05/25 Javascript
关于安卓手机微信浏览器中使用XMLHttpRequest 2上传图片显示字节数为0的解决办法
2016/05/17 Javascript
jquery实现静态搜索功能(可输入搜索文字)
2017/03/28 jQuery
JS实现排行榜文字向上滚动轮播效果
2019/11/26 Javascript
[02:22]完美世界DOTA2联赛PWL S3 集锦第一期
2020/12/15 DOTA
python求素数示例分享
2014/02/16 Python
Python的Django框架中从url中捕捉文本的方法
2015/07/20 Python
python2.7读取文件夹下所有文件名称及内容的方法
2018/02/24 Python
Python 多进程、多线程效率对比
2020/11/19 Python
HTML5 canvas基本绘图之绘制阴影效果
2016/06/27 HTML / CSS
html5+css3实现一款注册表单实例
2013/04/17 HTML / CSS
巴塞罗那观光通票:Barcelona Pass
2019/10/30 全球购物
介绍一下Linux文件的记录形式
2013/09/29 面试题
临床医学专业毕业生的自我评价
2013/10/17 职场文书
小学新学期教师寄语
2014/01/18 职场文书
服装设计师求职信
2014/06/04 职场文书
门店业绩提升方案
2014/06/08 职场文书
机电系毕业生求职信
2014/07/11 职场文书
群众路线教育实践活动实施方案
2014/10/31 职场文书
2015年大学生村官工作总结
2015/04/21 职场文书
超强台风观后感
2015/06/09 职场文书
七夕情人节问候语
2015/11/11 职场文书
Redis5之后版本的高可用集群搭建的实现
2021/04/27 Redis
Python matplotlib安装以及实现简单曲线的绘制
2022/04/26 Python