浅析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中pip安装非PyPI官网第三方库的方法
Jun 02 Python
Python脚本修改阿里云的访问控制列表的方法
Mar 08 Python
详解Python列表赋值复制深拷贝及5种浅拷贝
May 15 Python
python实现合并多个list及合并多个django QuerySet的方法示例
Jun 11 Python
对python中GUI,Label和Button的实例详解
Jun 27 Python
Python 余弦相似度与皮尔逊相关系数 计算实例
Dec 23 Python
如何利用pygame实现简单的五子棋游戏
Dec 29 Python
Python生成器常见问题及解决方案
Mar 21 Python
python实现控制台输出彩色字体
Apr 05 Python
Django bulk_create()、update()与数据库事务的效率对比分析
May 15 Python
使用 django orm 写 exists 条件过滤实例
May 20 Python
Python趣味实例,实现一个简单的抽奖刮刮卡
Jul 18 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
一个用mysql_odbc和php写的serach数据库程序
2006/10/09 PHP
php 表单验证实现代码
2009/03/10 PHP
PHP+RabbitMQ实现消息队列的完整代码
2019/03/20 PHP
Java 正则表达式学习总结和一些小例子
2012/09/13 Javascript
JavaScript?Apple设备检测示例代码
2013/11/15 Javascript
Node.js和PHP根据ip获取地理位置的方法
2014/03/14 Javascript
使用GruntJS构建Web程序之构建篇
2014/06/04 Javascript
JQuery悬停控制图片轮播——代码简单
2015/08/05 Javascript
整理Javascript数组学习笔记
2015/11/29 Javascript
使用递归遍历对象获得value值的实现方法
2016/06/14 Javascript
Angularjs过滤器实现动态搜索与排序功能示例
2017/12/13 Javascript
实例详解BootStrap的动态模态框及静态模态框
2018/08/13 Javascript
使用vue-cli3 创建vue项目并配置VS Code 自动代码格式化 vue语法高亮问题
2019/05/14 Javascript
js实现简单进度条效果
2020/03/25 Javascript
Electron整合React使用搭建开发环境的步骤详解
2020/06/07 Javascript
初学python数组的处理代码
2011/01/04 Python
使用PYTHON创建XML文档
2012/03/01 Python
Python中的ConfigParser模块使用详解
2015/05/04 Python
Python设计模式编程中解释器模式的简单程序示例分享
2016/03/02 Python
Python爬取十篇新闻统计TF-IDF
2018/01/03 Python
Python常见工厂函数用法示例
2018/03/21 Python
python获取代码运行时间的实例代码
2018/06/11 Python
利用pandas合并多个excel的方法示例
2019/10/10 Python
Django Admin后台添加数据库视图过程解析
2020/04/01 Python
python 两种方法删除空文件夹
2020/09/29 Python
python requests库的使用
2021/01/06 Python
基于HTML5代码实现折叠菜单附源码下载
2015/11/27 HTML / CSS
温泉秘密:Onsen Secret
2020/07/06 全球购物
创业者是否需要商业计划书?
2014/02/07 职场文书
《月光启蒙》教学反思
2014/03/01 职场文书
思想作风建设心得体会
2014/10/22 职场文书
区域经理岗位职责
2015/02/02 职场文书
2015年世界无烟日活动方案
2015/05/04 职场文书
经销商会议开幕词
2016/03/04 职场文书
Nginx的反向代理实例详解
2021/03/31 Servers
详解TS数字分隔符和更严格的类属性检查
2021/05/06 Javascript