python 构造函数继承_Python多重继承的异构构造器

在Python里面,如果你使用上Qt,SQLAlchemy,Twisted之类各种大型类库时候,有时候多重继承Multiple Inheritance是个简单的解决方法,但是多重继承的复杂性总容易造成误解和疑惑。

一般“常识”说,使用super访问父类的属性/方法,这种说法在多重继承里面是不成立的,多重继承的类并没有父类的概念(There is no superclass in a MI world)。类似的博客在过去几年被人写了无数遍了,因为过去版本里面python官方文档对super的解释非常有限而且有误导解释,直到2.6以后的文档,才详细说明了super在单继承和多继承的两种不同工作方式。当时苦逼的程序员甚至不得不去翻看Python源码才搞清楚是什么回事。以致几年来很多人对python的多重继承保持怀疑态度。

Python多重继承使用Method Resolution Order的动态算法来解决一个方法名的调用顺序,mro其实说来简单,就是一个深度优先的继承列表,很易理解,但随之来的是遇到互不相同的构造器__init__参数的问题。

Codepad运行结果:

class A(object):

def __init__(self, arg1):

print "init func in A, with arg1 '%s'" % arg1

super(A, self).__init__()

class B(object):

def __init__(self, arg1, arg2):

print "init func in B, with arg1'%s', arg2 '%s'" % (arg1, arg2)

super(B, self).__init__(arg1)

class C(B, A):

def __init__(self, arg1, arg2):

print "init func in C, with arg1'%s', arg2 '%s'" % (arg1, arg2)

super(C, self).__init__(arg1, arg2)

print C.__mro__

c = C("C's arg1", "C's arg2")

执行结果:

init func in C, with arg1'C's arg1', arg2 'C's arg2'

init func in B, with arg1'C's arg1', arg2 'C's arg2'

init func in A, with arg1 'C's arg1'

(, , , )

可见几个类的构造器的执行顺序正是mro列表的顺序。重点是多重继承的各个类的构造器__init__之所以能够执行,是因为每个构造器里面都有一句super(),这个super完成mro列表中下一个类的构造器的调用。

这个事实听起来似乎很自然,但看代码,B的构造器还得必须知道A的构造器的参数?B需要知道自己将会被C同时继承A,并且调用A的构造?!!很荒谬,但不幸的这是mro的特点。代码是可以这么写,但不应该,为另一个不知道什么时候会被一起继承的类特地地写代码,跟面对对象设计的解耦原则相违背。How

在mro方式的基础上,这个问题是不可能有效解决的,只能避免。概括起来大概有这么 两种方式。

1.使用传统类的方式,显式调用被继承类的构造器,避开super的mro自动化工作。

Codepad 看运行效果:

class A(object):

def __init__(self, arg1):

print "init func in A, with arg1 '%s'" % arg1

class B(object):

def __init__(self, arg1, arg2):

print "init func in B, with arg1'%s', arg2 '%s'" % (arg1, arg2)

class C(A, B):

def __init__(self, arg1, arg2):

print "init func in C, with arg1'%s', arg2 '%s'" % (arg1, arg2)

#super(C, self).__init__(arg1) #这两行

A.__init__(self, arg1) #等价

B.__init__(self, arg1, arg2)

print C.__mro__

c = C("C's arg1", "C's arg2")

注意 C继承A,B的顺序已经改变。

要排除一个容易产生的误解。Python文档里面的super有个很显著的Note:super() only works for new-style classes. super只适用于新类。但新类并不必须使用super。

直接调用被继承类的__init__作为unbound方法调用,需要指定一个实例,如self作为参数,依次调用各个被继承类。缺点是若果这几个被继承类也在构造方法里面使用这样调用了同一个上级被继承类,会出现“爷爷类”的构造方法被调用多次的情况。

如果一定使用super,要注意继承列表的顺序。super(TYPE, self).method调用的是mro列表中第一个,也即继承列表第一个类的方法。

PyQt里面的类内部一般(未细究)都使用__init__的方式来初始化代码,因而很多PyQt的例子代码都是使用QtGui.QMainWindow.__init__(self)这样的代码来初始化。当然在单继承时候和super的写法是等价的,但最好使用统一的原则:

一个简单好记的原则:

如果”被继承类”都使用__init__,”继承类”就使用__init__来初始化;

如果”被继承类”都使用super,”继承类”就使用super来初始化;

2.使用Composition / Association Pattern的设计模式(即’Is-A’转换成’Has-A’)来实现相同功能,避免多重继承。

这个方法听起来未免有点让人不快(破坏了原有设计思维),但实际上很可能这是更好的方式,更清晰的代码,尤其是要继承的类里面混合了使用super,__init__两种初始化方式的时候。;

玩蛇网文章,转载请注明出处和文章网址:https://www.iplaypy.com/jinjie/jj5808.html

相关文章 Recommend

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/558273.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android OpenGL Cannot create GL program: 0 GL error: 1282

Android OpenGL create GL program: 0 & GL error: 1282 快速解决 1. 使用GLSurfaceView的话 请在继承类中合适的地方(一般是构造函数里面)设置当前的clientversion 为 2 具体代码: setEGLContextClientVersion(2);2. 使用自己构建的opengl环境的话 请在创…

pythoncsv格式列变换_用Python将csv行转换为列

关于如何使用zip合并数据以及转置列表的一些提示。这听起来像是如何转置csv是你真正的问题。如何转置csv的答案是将其放入列表列表(例如通过csv模块),然后将其转置并写回文件(如果需要)。在row1 [1,2,3]row2 [a, b, c]list(zip(row1, row2))Out[45]: [(1, a), (2,…

Android DDMS的打开以及查看手机页面布局层次

ddms 查看android的界面布局层次 有时候看到一个比较好的界面或体验好的界面,就忍不住想看看其实现结果,那么可以通过DDMS工具来看相连设备层次以及使用哪些view。 上图是查看微信布局展现。说明,这里查看的就是显示在当前屏幕上的界面&am…

python转换窗口无响应_Tkinter窗口显示(没有响应),但代码正在运行

我有一个程序,在你点击一个操作按钮后运行一个很长的过程。当进程运行时,根窗口会说它没有响应,即使我知道程序是在后台运行的。这个程序将发布给我的几个同事,我想确保他们看到这个时不会惊慌失措,关上窗户。我的解决…

mac os11以下安装Xcode

前段时间mac重装系统,所有软件都清除了,下载从商店里面安装Xcode 12.5.1版本,直接提示“要求mac os 11.0或更高版本,于是乎开始升级mac os,检查更新并更新之后,最新版本就是macOS Catalina10.15.7&#xff…

fft之后求模值和相位_如何利用相位噪声测量表征时钟抖动来加速设计验证过程...

随着数据速率的提高,时钟抖动分析的需求也在与日俱增。在高速串行数据链路中,时钟抖动会影响发射机、传输线和接收机的数据抖动。时钟质量保证的测量方法也在不断发展。目前的重点是针对比特误码率(BER) 建立时钟性能和系统性能之间的直接联系。今天我们…

Android Studio 内存不足

android studio 4.2.2 编译的项目的时候,出现的内存不足问题,实际上android studio会有引导设置内存大小,可能都不太在意在哪个地方,设置完就完事了,在不提示的情况下可能找不到在哪设置,在此记录一笔。 出…

python寻找多数元素_寻找多数元素

定义:序列中的多数元素是指在一个元素个数为n的序列中,多数元素出现次数大于[n/2].寻找元素方法很多:1.可以暴力搜索,将每个元素都与其他元素作比较,然后统计该元素出现的次数,时间复杂度为O(n2)&#xff1…

mac 电脑安装 svn和brew

快速解决: 1. 安装svn brew install subversion 2. 安装brew 记得多尝试分别选择不同的下载源,鄙人最终是选择 “3 北京外国语大学” 成功的。 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"折…

监控mysql锁定状态_企业实战Mysql不停机维护主从同步

实战环境:Mysql-5.7Xtrabackup-2.4Xtrabackup 介绍:Percona XtraBackup是一款基于MySQL的服务器的开源热备份实用程序,在备份过程中不会锁定数据库。它可以备份来自MySQL5.1,5.5,5.6和5.7服务器上的InnoDB,…

Mac AndroidStudio常用快捷键

mac电脑的键盘修饰符对应关系 Command(或 Cmd)⌘Shift ⇧Option(或 Alt) ⌥Control(或 Ctrl)⌃Caps Lock ⇪esc ⎋Fn F6-F12的使用 单独按F6-F12,一般是控制电脑的音量、音乐上下曲的切换&a…

python缺失值类型与分析_3.1.1 缺失值分析

数据的缺失主要包括记录的缺失和记录中某个字段信息的缺失,两者都会造成分析结果的不准确,以下从缺失值产生的原因及影响等方面展开分析。(1)缺失值产生的原因1)有些信息暂时无法获取,或者获取信息的代价太大。2)有些信息是被遗漏的。可能是因…

为什么Mac source ~/.bash_profile只生效一次(macOS Catalina)

目录Mac环境变量的设置每次都要执行source ~/.bash_profile才有效解决方法(任选一种即可)一. 环境变量添加到.zshrc二 .zshrc中 添加source ~/.bash_profile三 切换mac的shell是什么原因Mac环境变量的设置 开发中对环境变量的修改和增加比较普遍,此处做为记录也供大…

三相四线怎样查漏电_老电工支招!漏电保护器的接线方法

家居装修中,电路问题是比较重要的,尤其是现在家居中使用的电器越来越多,所以漏电保护器是一定要的,能有很好的保护作用,那漏电保护器接线图是怎样的呢,漏电保护器接线方法以及注意事项有哪些,快…

view.post不执行的坑点

view.post没执行,runOnUiThread,Handler 目录坑点处理原因经历复盘6.0版本10.0版本总结坑点 子线程执行view.post(Runnable) 部分 手机没有效果。 usernameEditText.post(new Runnable() {Overridepublic void run() {usernameEditText.setText("…

扫地机器人划伤地板_扫地机器人哪个牌子好?会选的才能买到好产品

做为一种既时尚潮流又智能化的家用电器,扫地机器人一经面世就遭受大伙儿的关心。大家最先会感觉扫地机器人十分便捷,次之也会对它造成疑惑:就那么一台小小环形设备,确实能处理困惑人们这些年的打扫难题吗?事实上在扫地机器人的应用全过程中,客户对它的印像确实有很多种多样,有…

ThreadLocal初识

目录背景ThreadLocal的作用ThreadLocal特性ThreadLocal实现1. T get()2. set(T value)3. remove()验证一个对象只存一个数据多少个对象就能存多少个数据背景 这两天稍微有点空,在追溯之前的android 7.0之前的手机用View.post 出现不执行的问题时,结识了…

Gensee SDK UserInfo类函数详细说明

目录基本信息rolestatusclientType其他UserInfo是一个公共的类,用于RtSDK和PlayerSDK。由于role和status是复合1量,列出相关的判断方式,true为注释说明,false反之。 如 isHost() true 老师/false 不是老师。 基本信息 getUserId…

python中shutil模块_Python中shutil模块的学习笔记教程

介绍shutil 名字来源于 shell utilities,有学习或了解过Linux的人应该都对 shell 不陌生,可以借此来记忆模块的名称。该模块拥有许多文件(夹)操作的功能,包括复制、移动、重命名、删除等等一、chutil.copy(source, destination)shutil.copy()…

HTML转义字符大全<转>

为什么要用转义字符串&#xff1f; HTML中<&#xff0c;>&#xff0c;&等有特殊含义&#xff08;<&#xff0c;>&#xff0c;用于链接签&#xff0c;&用于转义&#xff09;&#xff0c;不能直接使用。这些符号是不显示在我们最终看到的网页里的&#xff0c…