浅析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 19 Python
python列表操作使用示例分享
Feb 21 Python
python实现电脑自动关机
Jun 20 Python
python 获得任意路径下的文件及其根目录的方法
Feb 16 Python
Python Tkinter 简单登录界面的实现
Jun 14 Python
用django-allauth实现第三方登录的示例代码
Jun 24 Python
Python的matplotlib绘图如何修改背景颜色的实现
Jul 16 Python
简单了解Python读取大文件代码实例
Dec 18 Python
Python自定义聚合函数merge与transform区别详解
May 26 Python
python如何从键盘获取输入实例
Jun 18 Python
keras分类之二分类实例(Cat and dog)
Jul 09 Python
python如何查找列表中元素的位置
May 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
PHP 删除文件与文件夹操作 unlink()与rmdir()这两个函数的使用
2011/07/17 PHP
如何取得中文字符串中出现次数最多的子串
2013/08/08 PHP
php的无刷新操作实现方法分析
2020/02/28 PHP
JS的千分位算法实现思路
2013/07/31 Javascript
Jjcarousellite 实现图片列表滚动的简单实例
2013/11/29 Javascript
javaScript 页面自动加载事件详解
2014/02/10 Javascript
jQuery+PHP+MySQL实现无限级联下拉框效果
2016/02/19 Javascript
jQuery常用知识点总结以及平时封装常用函数
2016/02/23 Javascript
js实现不重复导入的方法
2016/03/02 Javascript
基于JavaScript实现验证码功能
2017/04/01 Javascript
bootstrap栅格系统示例代码分享
2017/05/22 Javascript
vue-image-crop基于Vue的移动端图片裁剪组件示例
2018/08/28 Javascript
如何在Angular应用中创建包含组件方法示例
2019/03/23 Javascript
js实现GIF图片的分解和合成
2019/10/24 Javascript
Vuejs中的watch实例详解(监听者)
2020/01/05 Javascript
JS正则表达式验证端口范围(0-65535)
2020/01/06 Javascript
vue实现购物车功能(商品分类)
2020/04/20 Javascript
微信小程序视频弹幕发送功能的实现
2020/12/28 Javascript
[51:43]OG vs LGD 2018国际邀请赛淘汰赛BO3 第五场 8.26
2018/08/30 DOTA
python删除指定类型(或非指定)的文件实例详解
2015/07/06 Python
举例讲解Python设计模式编程的代理模式与抽象工厂模式
2016/01/16 Python
Python中matplotlib中文乱码解决办法
2017/05/12 Python
matplotlib简介,安装和简单实例代码
2017/12/26 Python
wxPython修改文本框颜色过程解析
2020/02/14 Python
python用TensorFlow做图像识别的实现
2020/04/21 Python
python 基于卡方值分箱算法的实现示例
2020/07/17 Python
Python confluent kafka客户端配置kerberos认证流程详解
2020/10/12 Python
python如何实现递归转非递归
2021/02/25 Python
ALEX AND ANI:手镯,项链,耳环和更多
2017/04/20 全球购物
bareMinerals官网:矿物质化妆品和护肤品
2018/02/04 全球购物
美津浓巴西官方网站:Mizuno巴西
2019/07/24 全球购物
英国行业制服供应商:Alexandra
2019/09/14 全球购物
Myprotein中国网站:欧洲畅销运动营养品牌
2021/02/11 全球购物
关于Java String的一道面试题
2013/09/29 面试题
2016年十一促销广告语
2016/01/28 职场文书
实现一个简单得数据响应系统
2021/11/11 Javascript