python全栈学习记录(二十一)类的继承、派生、组合

news2024/11/27 18:23:05

类的继承、派生、组合

文章目录

  • 类的继承、派生、组合
  • 一、类的继承
  • 二、派生
  • 三、组合

一、类的继承

继承是一种新建类的方式,新建的类称为子类,被继承的类称为父类。
继承的特性是:子类会遗传父类的属性(继承是类与类之间的关系)。

继承的好处就是可以减少代码的冗余。
在python中支持一个类同时继承多个父类。python3中如果一个类没有继承任何类,那默认继承object类,在python2中如果一个类没有继承任何类,不会继承object类。
新式类:但凡继承了object的类以及该类的子类都是新式类。
经典类:没有继承object的类以及该类的子类都是经典类。
在python3中都是新式类,只有在python2中才区别新式类与经典类。
新式类可以通过内置的__str__方法修改实例的打印值。

类继承类时只需要才()中写上需要继承的类即可,可以通过类的__bases__属性查看该类继承的类。

class A():
    pass

class B(A):
    def __str__(self):
        return 'from B'

print(B.__bases__)
b=B()
print(b)
<<< (<class '__main__.A'>,)
<<< from B

类的继承是为了减少代码的冗余:

class People:
    school='五道口职业技术学院'
    def __init__(self,name,age):
        self.name=name
        self.age=age

class Student(People):
    pass

class Teacher(People):
    pass

s=Student('张三',18)
t=Teacher('李四',40)
print(s.school,t.school)
print(s.name,t.name)
<<<五道口职业技术学院 五道口职业技术学院
<<<张三 李四

上述代码中Student和Teacher中没有__init__方法和school属性,初始化时就会取父类People中找。People作为Student和Teacher的父类,存储了__init__方法和school属性就避免了Student和Teacher中重复存储代码的问题。

菱形继承:当一个子继承多个父类时,多个父类最终继承了同一个类,称之为菱形继承
菱形继承的问题:

  • 经典类下查找属性:深度优先查找
  • 新式类下查找属性:广度优先查找

总结一下,类中属性查找,方法继承的方式为:实例、实例对应的类、父类

如果继承关系是非菱形的,类的继承会按直接继承的顺序先找完一条路,再去找其他的路。如图所示的继承顺序为:先找最左侧的路B、E,再找中间的路C,最后找右侧的路D、F。也可以通过mro表直接查看类的继承顺序。
在这里插入图片描述

class F():
    pass

class E():
    pass

class B(E):
    pass

class C():
    pass
class D(F):
    pass

class A(B,C,D):
    pass

print(A.__mro__)
<<< (<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.D'>, <class '__main__.F'>, <class 'object'>)

菱形继承的实现原理(新式类):图中的继承顺序为:首先按A的直接继承顺序找B这条路为B、E,到两条路相交的节点G后会跳转到下一条路C,再到下一条路D,找到D、F,当三条路全部找完以后再找节点G,之后再找F。

在这里插入图片描述

class H():
    pass

class G(H):
    pass
class F(G):
    pass

class E(G):
    pass

class B(E):
    pass

class C():
    pass
class D(F):
    pass

class A(B,C,D):
    pass

print(A.__mro__)
<<< (<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.D'>, <class '__main__.F'>, <class '__main__.G'>, <class '__main__.H'>, <class 'object'>)

由于一个类可以继承多个父类会导致复杂的菱形继承问题,所以python中设置了Mixins规范(阅读俗称的规范)

class Vehicle:
    pass

class FlyableMixin:
    """
    飞行功能
    """
    print('flying')
    
class CivilAircraft(FlyableMixin,Vehicle):
    pass

class Helicopter(FlyableMixin,Vehicle):
    pass

如上代码中CivilAircraft、Helicopter表示两种类型的飞机,而飞机既属于交通工具又能飞行,为了避免复杂的多类继承问题,我们人为规定FlyableMixin表示一种功能混入CivilAircraft、Helicopter继承的类中用以提示代码阅读者FlyableMixin并不被视为父类,而Vehicle才是真正的父类。
Mixins规范注意点:

  • mixins类必须表示某种功能混入继承的类中,且一般以mixin、able、ible为后缀
  • mixins类表示的功能单一,如果需要混入多个功能必须写多个mixins类
  • 子类即便没有继承mixins类依然可以工作,只是子类会缺少某个功能
  • mixins类功能的实现不依赖继承它的子类

二、派生

派生:子类中新定义的属性,子类在使用时始终以自己的为准。

class People:
    school='五道口职业技术学院'
    def __init__(self,name,age):
        self.name=name
        self.age=age

class Student(People):
    def __init__(self,name,age,class_name):
        #People.__init__(self,name,age)
        super(Student,self).__init__(name,age)
        self.class_name=class_name

s=Student('张三',18,'一班')
print(s.name,s.age,s.class_name)
<<<张三 18 一班

上述代码中Student类派生了People的__init__方法,加入了class_name参数的初始化。由于name和age参数的初始化在People类中已经存在,为了避免代码的重复,可以重用父类的__init__方法。重用的方法有两种,一种是直接指名道姓使用People类的__init__方法,这种方式必须将self参数也传如__init__方法中;另一种是使用super函数继承People类的__init__方式,这种方式无需传入self参数,super会自动将函数中的self传给父类的__init__方法。在python3中super()中的参数可以不写,但是python2中super()中传的参数必须写上,并且必须是新式类才能使用super。
注意点:

  • super函数会以调用super函数的类为起始按类的继承顺序向后寻找继承的方法。可以通过mro表查看super的继承顺序。
    __mro__和__bases__的区别在于__bases__只能查看类直接的继承顺序,而__mro__可以查看类所以的继承顺序。
class F():
    pass
class A(F):
    def f1(self):
        print('from A')
        super().f1()

class B():
    def f1(self):
        print('from B')

class C(A,B):
    def f1(self):
        print('from C')
        super().f1()

c=C()
print(C.__mro__)
print(C.__bases__)
<<< (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.F'>, <class '__main__.B'>, <class 'object'>)
<<< (<class '__main__.A'>, <class '__main__.B'>)
c.f1()
<<< from C
<<< from A
<<< from B

上述代码中c.f1()首先会运行C中的f1代码,然后运行super().f1(),此刻调用super的类是C,mro表中以C为起始向后寻找继承关系,找到A类的f1函数,再次运行super函数,再次在mro表中以A为起始向后找,找到B类,运行B的f1函数。

三、组合

组合就是一个类的对象具备某一个属性,该属性的值是指向另外外一个类的对象。
组合也是用来解决类与类直接代码冗余问题的。

class Course():
    def __init__(self,name,price):
        self.name=name
        self.price=price

class Teacher():
    def __init__(self,name):
        self.name=name
        self.course=[]

python=Course('python',1000)
c=Course('c',500)

t1=Teacher('张1')
t2=Teacher('张2')
#将t1、t2的course属性和python、c组合到一起以便于使用course属性可以直接参考price属性的值
t1.course.extend([python,c])
t2.course.append(c)
print(t1.course[0].price)
print(t2.course[0].price)
<<<1000
<<<500

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

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

相关文章

基于STM32的数字温度传感器设计与实现

引言 STM32 是由意法半导体&#xff08;STMicroelectronics&#xff09;开发的基于 ARM Cortex-M 内核的微控制器系列&#xff0c;以其强大的处理能力、丰富的外设接口和低功耗著称&#xff0c;广泛应用于嵌入式系统设计中。在这篇文章中&#xff0c;我们将介绍如何基于 STM32…

C++《string》

在之前的C语言学习当中我们已经了解了一系列的字符以及字符串函数&#xff0c;虽然这些函数也能实现对字符串进行求长度、拷贝、追加等操作&#xff0c;但是C语言当中的这些函数是与字符串分离的&#xff0c;并且最主要的是在使用这些函数时原字符串的底层空间是需要我们自己来…

微知-Intel芯片中的QPI是什么?本质是什么?以及其他几个高速总线的速率问题(快速通道互联,CPU之间互联总线)

基础信息 CPU与CPU之间通过QPI总线进行通信&#xff0c;类似CPU与PCI-E设备通过PCIE总线进行通信。 The Intel QuickPath Interconnect (QPI)&#xff1a;快速通道互联&#xff0c;快路径内部互联总线。是Inter-connect&#xff0c;内部互联的。是英特尔开发的一种高速点对点…

SpringBoot精华:打造高效美容院管理系统

第一章 绪论 1.1 选题背景 如今的信息时代&#xff0c;对信息的共享性&#xff0c;信息的流通性有着较高要求&#xff0c;尽管身边每时每刻都在产生大量信息&#xff0c;这些信息也都会在短时间内得到处理&#xff0c;并迅速传播。因为很多时候&#xff0c;管理层决策需要大量信…

BiLSTM模型实现电力数据预测

基础模型见&#xff1a;A020-LSTM模型实现电力数据预测 1. 引言 时间序列预测在电力系统管理、负荷预测和能源优化等领域具有重要意义。传统的单向长短期记忆网络&#xff08;LSTM&#xff09;因其在处理时间序列数据中的优势&#xff0c;广泛应用于此类任务。然而&#xff0…

用友NC service接口信息泄露漏洞

漏洞描述 用友NC service接口信息泄露漏洞&#xff0c;攻击者可通过构造恶意链接获取所有接口链接 公网上大部分服务器都没有修复此漏洞&#xff0c;可刷SRC 用友nc有个接口可以获取数据库账户密码&#xff0c;不过是老版本了 漏洞复现 app"用友-UFIDA-NC" POC …

哪家宠物空气净化器可以高效去除浮毛?希喂、IAM、有哈怎么样

在现代养宠家庭中&#xff0c;随着生活节奏的加快&#xff0c;清理浮毛也是很多家庭周末必须要做的事情。但是如何选择一款吸毛好、还不增加清理负担的宠物空气净化器&#xff0c;在寸土寸金的租房里为全家老小的健康生活保障&#xff1f;又如何通过强大的吸毛、除臭技术和除菌…

【学习笔记】手写一个简单的 Spring IOC

目录 一、什么是 Spring IOC&#xff1f; 二、IOC 的作用 1. IOC 怎么知道要创建哪些对象呢&#xff1f; 2. 创建出来的对象放在哪儿&#xff1f; 3. 创建出来的对象如果有属性&#xff0c;如何给属性赋值&#xff1f; 三、实现步骤 1. 创建自定义注解 2. 创建 IOC 容器…

IO模型介绍

一、理解IO 网络通信的本质就是进程间通信&#xff0c;进程间通信本质就是IO TCP中的IO接口&#xff1a;read / write / send / recv&#xff0c;本质都是&#xff1a;等 拷贝 所以IO的本质就是&#xff1a;等 拷贝 那么如何高效的IO&#xff1f; 减少“等”在单位时间的…

在VS code 中部署C#和avalonia开发环境

要在 Mac 的 VS Code 中配置 C# 和 Avalonia 的开发环境&#xff0c;您可以按照以下步骤进行&#xff1a; 1. 安装 .NET SDK 下载 .NET SDK&#xff1a; 访问 .NET 下载页面。选择适用于 macOS 的最新稳定版本的 .NET SDK&#xff0c;并下载安装程序。安装 .NET SDK&#xff1…

PADS自动导出Gerber文件 —— 6层板

在出GERBER文件之前要给PCB文件铺完铜并且检查连接性和安全间距无错误。进入CAM中之后点自动定义。如果电气层不需要用到2D线&#xff0c;保险起见在电气层中把2D线和文本去掉&#xff08;在DRC检查时2D线不会报错&#xff0c;文本是会报错的&#xff09;&#xff0c;因为有些时…

【JAVA开源】基于Vue和SpringBoot的校园资料分享平台

本文项目编号 T 059 &#xff0c;文末自助获取源码 \color{red}{T059&#xff0c;文末自助获取源码} T059&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

(功能测试)熟悉web项目及环境 测试流程

1.环境&#xff1f;有没有考虑过什么是环境&#xff1f; web网站为什么能打开&#xff1f; &#xff08;是因为他的服务器已经在运行了&#xff0c;网站服务器相关环境已部署及运行&#xff09; 所以什么是环境&#xff1f; 环境&#xff1a;就是项目运行所需要的软件及硬件组合…

php与python建站的区别有哪些

php与Python建站的区别&#xff1a; 1、语言层面Python的特性比php好&#xff0c;更加规范。 2、Python的性能比php高。 3、有只需要启动服务的时候执行一次的代码&#xff0c;在php里每个请求都会被执行一次&#xff0c;Python不需要。虽然php可以通过缓存缩短这方面的差距…

CVPR论文《DETRs Beat YOLOs on Real-time Object Detection》读后思维导图

下面欣赏一下论文中的图和表&#xff1a; 1、与YOLOs的性能对比图 2、不同置信度阈值下的框数 3、IoU阈值和置信度阈值对准确性和NMS执行时间的影响 4、混合编码器不同变体 5、模型概述。将骨干网后三个阶段的特征输入到编码器中。高效混合编码器通过基于注意力的尺度内特征交…

Linux网络基础:HTTPS 网络传输协议

HTTPS HTTPS 网络传输协议加密常见的加密方式&#xff08;对称/非对称加密&#xff09;数据摘要、数字签名HTTPS 加密过程探索的方案只使用对称加密&#xff08;效率低下、不安全&#xff09;只使用非对称加密&#xff08;不靠谱、不安全&#xff09;双方都使用非对称加密&…

js中的深拷贝与浅拷贝 手写深拷贝代码

1 什么是深拷贝和浅拷贝&#xff1f; 深拷贝和浅拷贝都是复制对象时常用的两种方式&#xff0c;区别在于对于嵌套对象的处理&#xff0c;浅拷贝只复制属性的第一层属性&#xff0c;双方修改嵌套对象将会互相影响。深拷贝会递归复制每一层的属性&#xff0c;修改任意一方互不影响…

YOLO11项目实战1:道路缺陷检测系统设计【Python源码+数据集+运行演示】

一、项目背景 随着城市化进程的加速和交通网络的不断扩展&#xff0c;道路维护成为城市管理中的一个重要环节。道路缺陷&#xff08;如裂缝、坑洞、路面破损等&#xff09;不仅影响行车安全&#xff0c;还会增加车辆的磨损和维修成本。传统的道路缺陷检测方法主要依赖人工巡检…

[云服务器17] 搭建PMail个性邮箱!我的邮箱我做主

哈喽大家好啊&#xff01; 我们先来看一个邮箱: 123456example163.com你发现了吗&#xff1f;后面有163的域名&#xff01; 这个就标志了邮箱服务提供商的名字&#xff0c;像常见的Outlook 163等。 那么作为一个追求自由主义的人&#xff0c;今天&#xff0c;我们就要使用开…

exe4j安装使用教程

A-XVK258563F-1p4lv7mg7sav A-XVK209982F-1y0i3h4ywx2h1 A-XVK267351F-dpurrhnyarva A-XVK204432F-1kkoilo1jy2h3r A-XVK246130F-1l7msieqiwqnq A-XVK249554F-pllh351kcke50