第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__方法深入剖析:构造方法与继承详解的更多相关文章

  1. 第8.2节 Python类的__init__方法深入剖析:构造方法案例详解

    前面一节介绍了构造方法定义的语法,并进行了语法解释说明,本节将通过案例来说明构造方法参数传递及返回值的情况. 一.    案例说明 本节定义一个汽车类,它有四个实例变量:wheelcount, pow ...

  2. Python 类中__init__()方法中的形参与如何修改类中属性的值

    一.__init__()方法 如果__init__()方法为 class Cat(): def __init__(self,num) : self.num=num Python中类的__init__( ...

  3. 第8.1节 Python类的构造方法__init__深入剖析:语法释义

    一.    引言 凡是面向对象设计的语言,在类实例化时都有构造方法,很多语言的构造方法名与类名一致,Python中类的构造方法比较特殊,必须是__init__特殊方法. 二.    语法释义 1.   ...

  4. 第7.14节 Python类中的实例方法详析

    第7.14节 Python类中的实例方法详析 一.    实例方法的定义 在本章前面章节已经介绍了类的实例方法,实例方法的定义有三种方式: 1.    类体中定义实例方法 第一种方式很简单,就是在类体 ...

  5. 第8.6节 Python类中的__new__方法深入剖析:调用父类__new__方法参数的困惑

    上节<第8.5节 Python类中的__new__方法和构造方法__init__关系深入剖析:执行顺序及参数关系案例详解>通过案例详细分析了两个方法的执行顺序,不知大家是否注意到了,在上述 ...

  6. 第8.12节 Python类中使用__dict__定义实例变量和方法

    上节介绍了使用实例的__dict__查看实例的自定义属性,其实还可以直接使用__dict__定义实例变量和实例方法. 一. 使用__dict__定义实例变量 语法: 对象名. dict[属性名] = ...

  7. 第7.17节 Python类中的静态方法装饰器staticmethod 定义的静态方法深入剖析

    第7.17节  Python类中的静态方法装饰器staticmethod 定义的静态方法深入剖析 静态方法也是通过类定义的一种方法,一般将不需要访问类属性但是类需要具有的一些能力可以静态方法提供. 一 ...

  8. 第三百五十五节,Python分布式爬虫打造搜索引擎Scrapy精讲—scrapy信号详解

    第三百五十五节,Python分布式爬虫打造搜索引擎Scrapy精讲—scrapy信号详解 信号一般使用信号分发器dispatcher.connect(),来设置信号,和信号触发函数,当捕获到信号时执行 ...

  9. python 类属性与方法

    Python 类属性与方法 标签(空格分隔): Python Python的访问限制 Python支持面向对象,其对属性的权限控制通过属性名来实现,如果一个属性有双下划线开头(__),该属性就无法被外 ...

随机推荐

  1. 无法将“add-migration”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。解决方案

    在程序包管理控制台中执行 Install-Package Microsoft.EntityFrameworkCore.Tools

  2. 命名管道FIFO及其读写规则

    一.匿名管道的一个限制就是只能在具有共同祖先的进程间通信命名管道(FIFO):如果我们想在不相关的进程之间切换数据,可以使用FIFO文件来做这项工作注意:命名管道是一种特殊类型文件.利用命令:$ mk ...

  3. 224、Basic Calculator

    Implement a basic calculator to evaluate a simple expression string. The expression string may conta ...

  4. 面试题:了解MySQL的Flush-List吗?顺便说一下脏页的落盘机制!(文末送书)

    Hi,大家好!我是白日梦! 今天我要跟你分享的MySQL话题是:"了解Flush-List吗?顺便说一下脏页的落盘机制!(文末送书)" 本文是MySQL专题的第 8 篇,共110篇 ...

  5. 西数WD2T硬盘分区对齐的方法

    新购一个西数2T硬盘,也就是绿盘的那种,淘宝500左右,支持高级格式化. 到手以后,分区格式化,前几天格式化完成以后,fdisk -l 发现如下文字 引用 Partition 1 does not s ...

  6. Math.floor(Math.random() * array.length),splice

    1.Math.floor(Math.random() * array.length) 返回长度内的索引 eg: changeLimit () { function getArrayItems(arr, ...

  7. idea中运行tomcat不能访问8080主页问题

    问题 初次使用IntelliJ IDEA,但今天在运行项目启动Tomcat后,发现无法访问Tomcat首页,出现404错误:输入http://localhost:8080时无法访问Tomcat首页,但 ...

  8. MapReduce的工作流程

    MapReduce的工作流程 1.客户端将每个block块切片(逻辑切分),每个切片都对应一个map任务,默认一个block块对应一个切片和一个map任务,split包含的信息:分片的元数据信息,包含 ...

  9. kali linux与虚拟机Vmware安装vmware tools(主机与虚拟机的文件拖拽)

    一.打开虚拟机任务栏"虚拟机"-----点击安装Vmware tools 二.回到开启的kali linux系统中,找到vmware tools CD文件夹,拖拽出文件中的压缩文件 ...

  10. Camtasia中对录制视频进行编辑——视觉效果

    视频剪辑对很多人来说是一件很头痛的事,因为对着屏幕一下一下的进行调整会让人十分的心烦,导致花费了时间但是剪辑出来的视频质量却并不高.或许是因为你没有选择一款合适的软件,因为一款高质量的软件往往会给人带 ...