第8.3节 Python类的__init__方法深入剖析:构造方法与继承详解
第8.3节 Python类的__init__方法深入剖析:构造方法与继承详解
一、 引言
上两节介绍了构造方法的语法及参数,说明了构造方法是Python的类创建实例后首先执行的方法,并说明如果类没有重写构造方法,Python将会给出默认的__init__方法。上述介绍适用于自定义类没有自定义父类的情况,如果自定义类是从其他自定义类派生的,又会怎样呢?
二、 构造方法与继承
为了保障相关逻辑的正确性,在子类重写构造方法时,必须调用超类(继承的类)的构造方法,否则可能无法正确地初始化对象。
1. 子类在构造方法处理时,可以有两种方法:
1> 继承后不重写构造方法,此时子类直接继承了父类的构造方法;
2> 重写父类构造方法,在子类的构造方法里显式地调用父类的构造方法,对调用执行的具体代码位置没有要求,可以在子类构造方法的开始部分、中间部分或结尾部分都可以,主要看业务逻辑有没有要求。
这两种方法都可以确保子类继承父类时构造方法的正确性。
2. 子类里显示调用父类的构造方法的三种实现方式
1> 父类名.父类构造方法,这种方法需要注意,self参数必须传给父类方法;
2> super().父类构造方法,这种方法调用不需要也不能传递self参数,由Python自动传入;
3> super(子类名,self).父类构造方法,这种方法调用也不需要传递self参数。
以上三种方法,老猿推荐大家使用第二种,一是使用简单,不需要给出父类名或子类名,也不需要self参数传递,二是程序修改简单,如果父类或子类名修改无需修改相关代码。不过这种方法只有Python3以后才支持。
三、 案例
1. 案例说明:
本节使用一个继承案例,超类为Vehicle(车),子类为car(小汽车),车只有3个实例变量:wheelcount(轮子数)、power(动力)、行驶总里程totaldistance,子类根据情况不同会有不同的实例变量,最多增加一个实例变量每公里油耗oilcostperkm(使用时错误,后面赋值时是按百公里油耗赋值的,特此说明)。为了聚焦问题,在类内都只定义构造方法,超类的类定义如下:
class Vehicle():
def __init__(self,wheelcount, power):
self.wheelcount,self.power,self.totaldistance = wheelcount,power,0
2. 案例1:子类不重写构造方法
1) 子类定义如下:
class Car(Vehicle):pass
此时应该继承父类的构造方法。
2) 没有写构造方法,不带参数执行实例定义,系统应报错
car=Car()
3) 按父类要求定义实例
car=Car(4,'汽油发动机') #带正确参数执行
4) 案例截图:

5) 案例总结:
子类继承父类构造方法,执行实例定义时直接执行该构造方法。
3. 案例2:子类重写构造方法但子类构造方法中不调用父类构造方法
1) 子类定义如下:
class Car(Vehicle): #子类重写构造方法但子类构造方法中不调用父类构造方法
def __init__(self,wheelcount, power,oilcostperkm):
self.oilcostperkm = oilcostperkm
print("In Car __init__:oilcostperkm=",self.oilcostperkm)。
2) 定义实例
car=Car(4,'汽油发动机',10)
3) 查看实例数据
car.__dict__ #查看实例自定义属性,应该只有oilcostperkm
car.wheelcount #查看实例的 wheelcount,应报错
4) 案例截图:

5) 案例总结:
子类重写构造方法,如果没有显示调用父类构造方法,则不会执行父类构造方法的相关代码。
4. 案例3:子类重写构造方法并调用父类构造方法
1) 子类定义如下:
class Car(Vehicle): #子类重写构造方法但子类构造方法中不调用父类构造方法
def __init__(self,wheelcount, power,oilcostperkm):
self.oilcostperkm = oilcostperkm
print("In Car __init__:oilcostperkm=",self.oilcostperkm)
super().__init__(wheelcount, power)
调用父类的构造方法,本例中用的这是一种老猿推荐的调用方法,还可以有下面两种调用方法:
Vehicle.__init__(self,wheelcount, power)
super(Car,self).__init__(wheelcount, power)
2) 定义实例和查看数据
car=Car(4,'汽油发动机',10) #应该执行两个构造方法
car.__dict__ #查看实例自定义属性,应该wheelcount, power,oilcostperkm都有
car.wheelcount #查看实例的 wheelcount,应正常给出
3) 案例截图:

4) 案例总结:子类重写构造方法,显示调用父类构造方法,相关实例变量都会正常初始化。
本节结合案例详细介绍了在继承情况下应该怎么实现子类的构造方法,内容比较简单但很重要,请大家注意。
老猿Python(https://blog.csdn.net/LaoYuanPython)系列文章用于逐步介绍老猿学习Python后总结的学习经验,这些经验有助于没有接触过Python的程序员可以很容易地进入Python的世界。
欢迎大家批评指正,谢谢大家关注!
第8.3节 Python类的__init__方法深入剖析:构造方法与继承详解的更多相关文章
- 第8.2节 Python类的__init__方法深入剖析:构造方法案例详解
前面一节介绍了构造方法定义的语法,并进行了语法解释说明,本节将通过案例来说明构造方法参数传递及返回值的情况. 一. 案例说明 本节定义一个汽车类,它有四个实例变量:wheelcount, pow ...
- Python 类中__init__()方法中的形参与如何修改类中属性的值
一.__init__()方法 如果__init__()方法为 class Cat(): def __init__(self,num) : self.num=num Python中类的__init__( ...
- 第8.1节 Python类的构造方法__init__深入剖析:语法释义
一. 引言 凡是面向对象设计的语言,在类实例化时都有构造方法,很多语言的构造方法名与类名一致,Python中类的构造方法比较特殊,必须是__init__特殊方法. 二. 语法释义 1. ...
- 第7.14节 Python类中的实例方法详析
第7.14节 Python类中的实例方法详析 一. 实例方法的定义 在本章前面章节已经介绍了类的实例方法,实例方法的定义有三种方式: 1. 类体中定义实例方法 第一种方式很简单,就是在类体 ...
- 第8.6节 Python类中的__new__方法深入剖析:调用父类__new__方法参数的困惑
上节<第8.5节 Python类中的__new__方法和构造方法__init__关系深入剖析:执行顺序及参数关系案例详解>通过案例详细分析了两个方法的执行顺序,不知大家是否注意到了,在上述 ...
- 第8.12节 Python类中使用__dict__定义实例变量和方法
上节介绍了使用实例的__dict__查看实例的自定义属性,其实还可以直接使用__dict__定义实例变量和实例方法. 一. 使用__dict__定义实例变量 语法: 对象名. dict[属性名] = ...
- 第7.17节 Python类中的静态方法装饰器staticmethod 定义的静态方法深入剖析
第7.17节 Python类中的静态方法装饰器staticmethod 定义的静态方法深入剖析 静态方法也是通过类定义的一种方法,一般将不需要访问类属性但是类需要具有的一些能力可以静态方法提供. 一 ...
- 第三百五十五节,Python分布式爬虫打造搜索引擎Scrapy精讲—scrapy信号详解
第三百五十五节,Python分布式爬虫打造搜索引擎Scrapy精讲—scrapy信号详解 信号一般使用信号分发器dispatcher.connect(),来设置信号,和信号触发函数,当捕获到信号时执行 ...
- python 类属性与方法
Python 类属性与方法 标签(空格分隔): Python Python的访问限制 Python支持面向对象,其对属性的权限控制通过属性名来实现,如果一个属性有双下划线开头(__),该属性就无法被外 ...
随机推荐
- 天啦噜!仅仅5张图,彻底搞懂Python中的深浅拷贝
Python中的深浅拷贝 在讲深浅拷贝之前,我们先重温一下 is 和==的区别. 在判断对象是否相等比较的时候我们可以用is 和 == is:比较两个对象的引用是否相同,即 它们的id 是否一样 == ...
- DevExpress XtraReport报表预览时可编辑的功能
设置控件的EditOptions.Enabled=true即可 注册实现PrintingSystem. EditingFieldChanged事件,可获得当前发生更改的控件的值. 另:XtraRepo ...
- windows鼠标右键文件太多
1.网上找的(已经验证太难找,并没有多大用) 单击Windows的"开始"菜单,单击"运行",在"打开"框中键入"regedit& ...
- 18FlaskRESTful
一,虚拟环境下安装(win) 在安装这个环节发现了很多问题,pycharm里装了之后发现根本引用不了,查明原因是因为第三方库pycharm无法识别. 解决办法:进入虚拟环境直接pip. 二,基本使用 ...
- 329. Longest Increasing Path in a Matrix(核心在于缓存遍历过程中的中间结果)
Given an integer matrix, find the length of the longest increasing path. From each cell, you can eit ...
- xctf攻防世界——crackme writeup
感谢xctf提供学习平台 https://adworld.xctf.org.cn crackme有壳,脱壳部分见文章: https://www.cnblogs.com/hongren/p/126332 ...
- php递归无限查询上级或者下级
$this->get_array($user['uid'],1); function get_array($user_id,$top=0){ $sql = 'SELECT * FROM ' . ...
- 使用phpExcel读取excel文件
include_once '../include/common.inc.php'; include_once MC_ROOT.'include/smarty.inc.php'; date_defaul ...
- 细说FL Studio中的Wasp合成器功能
FL Studio 简称FL,因其Logo像水果,故国人亲切的叫他"水果"本章节采用图文结合的方式给大家讲解FL Studio中的Wasp合成器功能.感兴趣的朋友可以一起来交流哦. ...
- 在FL Studio中如何更好地为人声加上混响(进阶教程)
为人声加上混响是我们在处理人声过程中必不可少的一步.然而,除了直接在人声混音轨道加上混响插件进行调节以外,这里还有更为细节的做法可以达到更好的效果. 步骤一:使用均衡器 在为人声加上混响之前,我们应该 ...