浅析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写的Socks5协议代理服务器
Aug 06 Python
浅谈Python爬取网页的编码处理
Nov 04 Python
对python .txt文件读取及数据处理方法总结
Apr 23 Python
详解Python3.6的py文件打包生成exe
Jul 13 Python
Python实现的简单计算器功能详解
Aug 25 Python
pycharm运行和调试不显示结果的解决方法
Nov 30 Python
python paramiko利用sftp上传目录到远程的实例
Jan 03 Python
Python面向对象之继承和多态用法分析
Jun 08 Python
Python环境Pillow( PIL )图像处理工具使用解析
Sep 12 Python
python自动化unittest yaml使用过程解析
Feb 03 Python
python实现将range()函数生成的数字存储在一个列表中
Apr 02 Python
selenium切换标签页解决get超时问题的完整代码
Aug 30 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
利用yahoo汇率接口实现实时汇率转换示例 汇率转换器
2014/01/14 PHP
PHP格式化MYSQL返回float类型的方法
2016/03/30 PHP
深入理解PHP的远程多会话调试
2017/09/21 PHP
浅谈PHP中的Trait使用方法
2019/03/22 PHP
php设计模式之策略模式应用案例详解
2019/06/17 PHP
php变量与字符串的增删改查操作示例
2020/05/07 PHP
Ext 表单布局实例代码
2009/04/30 Javascript
用Jquery实现多级下拉框无刷新的联动
2010/12/22 Javascript
HTML Color Picker(js拾色器效果)
2013/08/27 Javascript
JavaScript自定义事件介绍
2013/08/29 Javascript
巧用局部变量提升javascript性能
2014/02/24 Javascript
jquery选择器排除某个DOM元素的方法(实例演示)
2014/04/25 Javascript
chrome下jq width()方法取值为0的解决方法
2014/05/26 Javascript
node.js中的buffer.fill方法使用说明
2014/12/14 Javascript
javascript制作网页图片上实现下雨效果
2015/02/26 Javascript
javascript实现判断鼠标的状态
2015/07/10 Javascript
使用jQuery实现动态添加小广告
2017/07/11 jQuery
详解如何使用webpack+es6开发angular1.x
2017/08/16 Javascript
javascript计算渐变颜色的实例
2017/09/22 Javascript
Node.js log4js日志管理详解
2018/07/31 Javascript
javascript 使用sleep函数的常见方法详解
2020/04/26 Javascript
用ReactJS和Python的Flask框架编写留言板的代码示例
2015/12/19 Python
解决Python一行输出不显示的问题
2018/12/03 Python
Django中reverse反转并且传递参数的方法
2019/08/06 Python
使用matlab或python将txt文件转为excel表格
2019/11/01 Python
Django3.0 异步通信初体验(小结)
2019/12/04 Python
python opencv 图像边框(填充)添加及图像混合的实现方法(末尾实现类似幻灯片渐变的效果)
2020/03/09 Python
Python实现加密的RAR文件解压的方法(密码已知)
2020/09/11 Python
CSS3的颜色渐变效果的示例代码
2017/09/29 HTML / CSS
路易威登和香奈儿手袋:LuxeDH
2017/01/12 全球购物
Windows和Linux动态库应用异同
2016/04/17 面试题
最新优秀教师个人先进事迹材料
2014/05/06 职场文书
2015年万圣节活动总结
2015/03/24 职场文书
毕业生学校组织意见
2015/06/04 职场文书
left join、inner join、right join的区别
2021/04/05 MySQL
解决Laravel使用验证时跳转到首页的问题
2021/11/17 PHP