当前位置: 首页 > news >正文

B站清华128小时Python高级教程一(C3深入类和对象)

Chapter3  深入类和对象

一、多态和鸭子类型

1、多态:与继承(是指发生在子类和父类之间的)、重写(子类重写父类中的方法)相关。

class Animal:def say(self):print('I am an animal.')class Cat(Animal):def say(self):print('I am a cat.')class Dog(Animal):def say(self):print('I am a dog.')class Duck(Animal):def say(self):print('I am a duck.')duck = Duck()
duck.say()dog = Dog()
dog.say()

多态中的“重写父类方法”也是面向对象语言的一种通用方式。

2、所谓的鸭子方法听视频里讲基本就是对一个对象(变量)而言,不管它实际是什么,一会儿指向A,一会儿指向B,再指向C,只需要保证任何时候这个对象(变量)都具有同一种方法即可。

如下代码中变量animal先被赋值为Cat类,后被赋值为Duck类,但它都可以实现say()方法。

class Cat:def say(self):print('I am a cat.')class Dog:def say(self):print('I am a dog.')class Duck:def say(self):print('I am a duck.')animal = Cat
animal().say()animal = Duck
animal().say()
# 关于鸭子类型的实现案例
list_a = [1, 2]
list_b = [3, 4]
list_a.extend(list_b)     #这里的可追加显而易见,因为list_a和list_b都同属列表类型
print(list_a)set_data = set()
set_data.add(5)
set_data.add(6)# 能否再继续在list_a上追加集合set_data呢
list_a.extend(set_data)
print(list_a)        #依然可以
# 那么为何可以呢?list_a是列表,而set_data是集合
# 原因就在于extend()方法实现上只需要是迭代类型就可以进行追加
# 这里list和set两种类型都实现了可迭代功能,这种情况也称之为“鸭子类型”

 二、抽象基类

在原先如Java中是不支持多继承的,那么针对这种需求,JAVA会提供一个特殊的类,即抽象类,无法实例化,且可以被继承,且继承抽象流之后必须重载(重写)这个抽象类的方法。

Python中也有抽象类,其作用一般为:1、进行类型判断;2、对类的方法进行限制。

如Sized就是一个python中的抽象基类,同样有:1、无法被实例化;2、继承它的类定义时须重写其方法(对Sized类这里的方法就是__len__()方法)。

其中第1条无法被实例化的原因是否也是因为这个抽象基类并没有真正实现其内部方法呢?导致实例化对象方法缺陷报错?

梳理一下:

*为什么需要抽象基类?

Python 是动态语言,默认没有“接口”或“强制契约”的概念。但在大型项目或团队协作中,我们希望:
  • 某些类不能直接使用,只能被继承;
  • 所有子类必须实现特定方法,避免遗漏;
  • 能通过 isinstance() 判断对象是否符合某种“行为协议”。
为了解决这些问题,Python 提供了 抽象基类(Abstract Base Class, ABC) 机制,通过标准库模块 abc 实现。

*抽象基类的核心作用

    1. 强制子类实现指定方法
      如果子类没有重写所有抽象方法,尝试实例化时会抛出 TypeError
    2. 支持类型判断(协议式编程)
      可用 isinstance(obj, MyABC) 判断对象是否符合某个抽象接口,即使它不是直接继承而来。

*抽象基类的定义

使用 abc 模块中的 ABC 类和 @abstractmethod 装饰器:

from abc import ABC, abstractmethodclass Animal(ABC):@abstractmethoddef make_sound(self):pass  # 抽象方法,子类必须实现class Dog(Animal):def make_sound(self):return "Woof!"# 错误示例:未实现抽象方法
# class Cat(Animal):
#     pass
# Cat()  # 报错:Can't instantiate abstract class Cat with abstract method make_sound

  对于上例中Cat类未实现抽象基类的方法而报错,这里的报错功能是由ABC类提供;而装饰器@abstractmethod是用来标识一个抽象基类中哪些方法是需要被重写的,ABC类需要先检查这个抽象类中有哪些必须重写的方法。(如已标识为必须重写的方法未重写,即报错)

 三、关于isinstance()和type()方法的区别

class A:passclass B(A):passb = B()# 判断b与A,B是否是同一类型
# 用isinstance判断
print(isinstance(b, B))     #输出true
print(isinstance(b, A))     #输出true# 用type判断
print(type(b) is B)     #输出true
print(type(b) is A)     #输出false

 

instance()和type()的区别在于,type()只会返回和被判别对象本身的“类别”,并不会返回其父类。而instance()中只要存在继承关系,都判别为true.

对任意对象,下例都满足。

print(isinstance(b, object))

 四、类变量与实例变量(对象变量)的区别 

class A:#   类变量b = 1def __init__(self, x, y):#   实例变量self.x = xself.y = ya = A(2, 3)#   实例对象可以访问实例变量和类变量
print(a.x, a.y, a.b)#   类访问类变量
print(A.b)#   使用类去修改类变量,并用实例对象访问类对象
A.b = 18
print(A.b)
print(a.b)   #  先前创建的实例对象再去访问类变量,可以发现同样也改变了,说明这里是“引用类型”#   使用实例对象去修改类变量
a.b = 26
print(A.b)      #   可以发现类变量并没有变化
print(a.b)      #   但是实例对象访问b却发生了改变
#   这里根本的原因是a.b = 26这一句的实质是给实例对象新创建了一个实例变量,这个实例变量只归属于这个实例对象
#   也就是说实例对象是无法修改类变量的#   再使用类去修改类变量
A.b = 28
print(A.b)      # 28
print(a.b)      # 26,访问的还是a之前新创建的实例变量b,而非类变量b

 五、类变量与实例变量以及查找顺序 

class A:name = 'A'def __init__(self):self.name = 'obj'a = A()
#   访问name变量,会在a内部先查找实例对象,如果没有,再去类中找
print(a.name)

类的多继承查找一般有两种方式:深度优先和广度优先;不同的继承关系有着不同的调用顺序

#   深度优先:从左往右查找,对A来说,即先查找B,再找D,再找C,再找E,再找Object,再没有就抛出异常
class E:passclass D:passclass C(E):passclass B(D):passclass A(B, C):pass#   通过mro方法进行查找顺序的打印
print(A.__mro__)
# 输出:(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.C'>, <class '__main__.E'>, <class 'object'>)

 

#   广度优先
class D:passclass C(D):passclass B(D):passclass A(B, C):pass# 通过mro方法进行查找顺序的打印
print(A.__mro__)

 

http://www.jsqmd.com/news/394767/

相关文章:

  • 题解:洛谷 B2016 浮点数向零舍入
  • 专科生必看!倾心之选的一键生成论文工具 —— 千笔ai写作
  • 2026重庆火锅热推榜,这些美味不容你错过!火锅店/美食/特色美食/火锅/社区火锅,火锅品牌必吃榜 - 品牌推荐师
  • 写了 10 年后端,看到 XinServer 后端平台我哭了
  • 2026衬塑衬四氟管道哪家强?本地工厂预制化管道品牌榜出炉,碳钢管道/耐磨管件/高压管件/管道,工厂预制化管道品牌排行 - 品牌推荐师
  • 给你一张清单 9个降AI率平台测评对比 专科生必看
  • 实用指南:软件工程计算机网络WindowService2008 DNS DHCP网络策略和访问策略IIS 相关配置 期末考试实操题操作题windows运维
  • 题解:洛谷 B2015 计算并联电阻的阻值
  • 用过才敢说 8个AI论文网站测评:专科生毕业论文+开题报告高效写作指南
  • 基于海雅达 Model 10X 工业平板的车间生产线旁站控制方案 - 实践
  • Stable Diffusion的3个替代方案
  • 用数据说话 10个降AI率平台测评:专科生必看!降AI率工具全对比
  • 2026年尘埃粒子计数器优质厂家盘点,选购指南来袭,手持式尘埃粒子计数器/便携式粒子计数器,尘埃粒子计数器厂家电话 - 品牌推荐师
  • 写论文省心了!千笔,最受欢迎的一键生成论文工具
  • 题解:洛谷 B2013 温度表达转化
  • 题解:洛谷 B2014 与圆相关的计算
  • Claude Teach Me:白领的威胁
  • LeetCode696:计数二进制串
  • 并行运行编码代理
  • 7个AI工程必备Python库
  • 软件即产品已成沉疴
  • Stanford-CS336-Lecture-01 学习理解
  • 用3个提示创建2D CFD求解器
  • 题解:洛谷 B2011 计算分数的浮点数值
  • 什么是AI销冠系统和AI提效软件系统?主要区别和应用场景是什么?
  • 2026制氮机供应商优选榜:这些品牌值得关注,制氧机/二氧化碳/制氮机/汽化器/真空管/液氮速冻机,制氮机厂商怎么选择 - 品牌推荐师
  • 题解:洛谷 B2080 计算多项式的值
  • 学习笔记——时钟系统与定时器 - 指南
  • 亲测好用! AI论文网站 千笔 VS PaperRed,专科生写作更轻松!
  • 2026质量好的育肥牛料供应厂家全知道,东北饲料/三七乳猪料/百吉纳饲料/专利饲料/阿迪斯饲料,育肥牛料源头厂家推荐 - 品牌推荐师