【Python】使用super初始化超类
初始化超类的传统方式,在子类的实例中调用超类的__init__()方法。
但是传统的方法有两个问题,比如:
问题1:
class MyBaseClass:
def __init__(self, value):
self.value = value class TimesTwo:
def __init__(self):
self.value *= 2 class PlusFive:
def __init__(self):
self.value += 5 class OneWay(MyBaseClass, TimesTwo, PlusFive):
def __init__(self,value):
MyBaseClass.__init__(self, value)
TimesTwo.__init__(self)
PlusFive.__init__(self) class AnotherWay(MyBaseClass, PlusFive, TimesTwo):
def __init__(self,value):
MyBaseClass.__init__(self, value)
TimesTwo.__init__(self)
PlusFive.__init__(self) foo = OneWay(5)
print('OneWay (5*2)+5=', foo.value)
foo = AnotherWay(5)
print('AnotherWay:', foo.value)
结果为:

从结果可以看出,即使改变了子类的继承顺序,调用的顺序并没有改变。
问题2:
如果子类继承自两个单独的超类,而那两个超类又继承自同一个公共基类,那么就构成了钻石型继承。
这种继承会使钻石顶端的公共基类多次执行__init__()方法,从而产生意外。
比如:
class MyBaseClass:
def __init__(self, value):
self.value = value class TimesFive(MyBaseClass):
def __init__(self, value):
MyBaseClass.__init__(self, value)
self.value *= 2 class PlusTwo(MyBaseClass):
def __init__(self, value):
MyBaseClass.__init__(self, value)
self.value += 2 class ThisWay(TimesFive, PlusTwo):
def __init__(self, value):
TimesFive.__init__(self, value)
PlusTwo.__init__(self, value) foo = ThisWay(5)
print('Should be (5*5)+2 but is ', foo.value)
在调用PlusTwo.__init__()时候,又一次调用MyBaseClass.__init__()又一次把value变为5
以上两种问题都可以使用super解决,方法解析顺序mro(method resolution order),以标准的流程安排超类之间的初始化顺序。
比如这次用super初始化超类
class MyBaseClass:
def __init__(self, value):
self.value = value class TimesFive(MyBaseClass):
def __init__(self, value):
super(TimesFive, self).__init__(value)
self.value *= 5 class PlusTwo(MyBaseClass):
def __init__(self, value):
super(PlusTwo, self).__init__(value)
self.value += 2 class GoodWay(TimesFive, PlusTwo):
def __init__(self, value):
super(GoodWay, self).__init__(value) foo = GoodWay(5)
print('Should be 5*(5+2) and is ', foo.value)
并且可以使用
print(GoodWay.mro())
来查看初始化顺序:

参考资料:Effective Python
【Python】使用super初始化超类的更多相关文章
- 【转】python 调用super()初始化报错“TypeError: super() takes at least 1 argument”
一.实验环境 1.Windows7x64_SP1 2.Anaconda2.5.0 + python2.7(anaconda集成,不需单独安装) 二.实验步骤 2.1 在python中有如下代码: cl ...
- java中构造方法和方法super/this超类与子类中初始化顺序
java中构造方法和方法全面解析 我相信大多说人都对构造方法.方法不陌生,而且很了解,但我也相信有很多像我这样的没有一个很好很清晰很全面的认识,今天就把它整理如下,希望能给大家带来点方便与帮助,也希望 ...
- python之super()函数
python之super()函数 python的构造器奇特, 使用魔方. 构造器内对基类对象的初始化同样也很奇特, 奇特到没有半点优雅! 在构造器中使用super(class, instance)返回 ...
- 由Python的super()函数想到的
python-super *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !im ...
- Python: 你不知道的 super
https://segmentfault.com/a/1190000007426467 Python: 你不知道的 super 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我 ...
- python的super深入了解(转)
1.python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通方法和super方法 假设Base是基类 class Base(object): def __init__(s ...
- python的super()以及父类继承
Python中子类调用父类的方法有两种方法能够实现:调用父类构造方法,或者使用super函数(两者不要混用). 使用“super”时经常会出现代码“super(FooChild,self).__ini ...
- 扯下Python的super()
注: Python 2.7.x 环境下 今晚搜东西无意中看到这篇Understanding Python super() with __init__() methods. 其实这篇老早就看过了, 不过 ...
- python中super的理解(转)
原文地址:https://www.zhihu.com/question/20040039 针对你的问题,答案是可以,并没有区别.但是这题下的回答我感觉都不够好. 要谈论 super,首先我们应该无视 ...
随机推荐
- memcache总结
1简介: Memcache(内存缓存) 是一个高性能的分布式的内存对象缓存系统.通过在内存里维护一个巨大的hash表. 其实简单说点就是一个软件,可以用来维护内存,将数据在内存中使用,减少I/O 2工 ...
- 解决js中传值,Action获取是乱码问题
1.先在js中进行编码 var str = $("mytext").val(); //转码,两次 str = encodeURI(str); str = encodeURI(str ...
- SQLSERVER之高灵活的业务单据流水号生成
SQLSERVER之高灵活的业务单据流水号生成 最近的工作中要用到流水号,而且业务单据流水号生成的规则分好几种,并非以前那种千篇一律的前缀+日期+流水号的简单形式,经过对业务的分析,以及参考网上程序员 ...
- 基于Hadoop开发网络云盘系统架构设计方案
基于Hadoop开发网络云盘系统架构设计方案第一稿 引言 云计算技术的发展,各种网络云盘技术如雨后春笋,层出不穷,百度.新浪.网易都推出了自己的云盘系统,本文基于开源框架Hadoop设计实现了一套自己 ...
- Shell 获取当前执行脚本的路径
filepath=$(cd "$(dirname "$0")"; pwd) 脚本文件的绝对路径存在了环境变量filepath中,可以用 echo $filepa ...
- jquery 表单 清空
做了个复杂查询的页面,字段太多了,填了一次,想清空挺麻烦的 $('#myform')[0].reset(); 虽然reset方法可以做到一部分,但是如果你有个元素是这样的 <input name ...
- 哈工大数据库系统 实验:练习并熟练掌握交互式 SQL 语言
实验目的:基于给定的 OrderDB 数据库, 练习并熟练掌握交互式 SQL 语言实验环境:sql sever 2008 附:OrderDB 表结构及表间的关系 /* 1 查询职工工资按高低排序的前2 ...
- H5 拖放事件详解
拖放事件 H5的拖放事件提供了多个接口: 1.drag:当元素或者选中的文本被拖动时触发(每几百毫秒触发一次),应用在被拖拽元素上 2.dragend:当拖动操作结束时触发(通过释放鼠标按钮或者点击转 ...
- Extjs的GridPanel分页前后台完整代码实例
第一次写文章啊,有些冲动.最近在公司学习Extjs,做了一个分页的小实例和大家分享. 1.首先编写paging-grid.js文件,这是我在网上参考的例子改写的,大同小异. Ext.onReady(f ...
- 瑶瑶GBK好的,UTF-8卡死
请求地址: 开发环境核心 esb : http://10.15.22.120:8866/0203000007/EmpAndDptRelateInfoSync/V1 用gbk可以马上返回. 用utf-8 ...