python中的抽象类在项目中的实际应用
抽象类在项目中的实际应用主要体现在 规范代码结构、强制子类实现某些方法、提供部分通用功能,让代码更稳定、易维护。
举个例子:数据校验器
假设你在做一个 用户输入校验系统,需要支持 数字校验、字符串校验 和 邮箱校验。如果不用抽象类,每个校验器都会自己定义 validate()
方法,开发者可能忘了统一标准,导致代码不一致。
用抽象类改进
from abc import ABC, abstractmethodclass Validator(ABC): """抽象类:所有校验器的基类,规定必须有 validate 方法"""@abstractmethoddef validate(self, value):"""子类必须实现这个方法,否则会报错"""pass class NumberValidator(Validator): """数字校验器"""def validate(self, value):return isinstance(value, (int, float)) # 只接受数字class EmailValidator(Validator): """邮箱校验器"""def validate(self, value):return isinstance(value, str) and "@" in value # 简单的邮箱格式检查# 试试用这些校验器:
num_validator = NumberValidator()
print(num_validator.validate(123)) # True
print(num_validator.validate("abc")) # Falseemail_validator = EmailValidator()
print(email_validator.validate("test@example.com")) # True
print(email_validator.validate(123)) # False
为什么用抽象类?
-
强制所有校验器实现
validate()
Validator
规定了必须有validate()
,如果子类忘记写,Python 会报错,避免代码不完整:
class BadValidator(Validator):pass # 忘了写 validate 方法obj = BadValidator() # TypeError: Can't instantiate abstract class BadValidator with abstract method validate
-
代码更清晰,扩展更方便
- 如果以后要加 日期校验器 之类的,只需要继承
Validator
并实现validate()
,不会影响现有代码:
class DateValidator(Validator):def validate(self, value):return isinstance(value, str) and "-" in value # 简单日期格式检查
- 如果以后要加 日期校验器 之类的,只需要继承
-
减少重复代码,提供通用功能
- 抽象类不仅能定义“必须实现的方法”,还能提供公共方法:
class Validator(ABC):@abstractmethoddef validate(self, value):passdef is_valid(self, value):"""包装一下 validate 方法,返回 True/False"""try:return self.validate(value)except:return False
总结
- 抽象类 是“半成品”类,不能直接用,必须让子类去填充关键方法(比如
validate()
)。 - 强制子类实现关键方法,避免开发者忘记写,导致功能缺失。
- 让代码结构清晰,团队合作时,每个校验器都符合相同规则,方便扩展。
- 可以提供部分通用功能,减少重复代码。
举个例子:日志记录系统
假设你在开发一个日志系统,需要支持 控制台日志、文件日志 和 数据库日志。
如果不用抽象类,每个日志处理类可能命名、方法都不一样,导致代码风格混乱、调用方式不统一。
不用抽象类(混乱)
class ConsoleLogger:def log_message(self, msg):print(f"Console: {msg}")class FileLogger:def write_log(self, msg):with open("log.txt", "a") as f:f.write(f"File: {msg}\n")class DatabaseLogger:def save(self, msg):print(f"Saving '{msg}' to database...")
问题:
- 每个日志类的方法名字不一样 (
log_message()
、write_log()
、save()
),调用时不统一。 - 如果有人写了
NetworkLogger
,他可能又起个新名字,比如send_log()
,代码越来越乱。
用抽象类改进
from abc import ABC, abstractmethodclass Logger(ABC):"""抽象类:所有日志类的基类"""@abstractmethoddef log(self, msg):"""子类必须实现这个方法"""pass class ConsoleLogger(Logger):"""控制台日志"""def log(self, msg):print(f"Console: {msg}")class FileLogger(Logger):"""文件日志"""def log(self, msg):with open("log.txt", "a") as f:f.write(f"File: {msg}\n")class DatabaseLogger(Logger):"""数据库日志"""def log(self, msg):print(f"Saving '{msg}' to database...")# 统一调用方式
def process_logs(logger: Logger, message: str):"""统一的日志处理逻辑"""logger.log(message)# 使用不同日志处理器
console_logger = ConsoleLogger()
file_logger = FileLogger()
db_logger = DatabaseLogger()process_logs(console_logger, "This is a console log.")
process_logs(file_logger, "This is a file log.")
process_logs(db_logger, "This is a database log.")
为什么用抽象类?
-
所有日志类的方法名保持一致
- 统一用
log(msg)
,不管是控制台、文件还是数据库,代码调用方式完全一样,方便维护和扩展。
- 统一用
-
强制子类实现
log()
方法- 如果开发者新写
NetworkLogger
但忘记实现log()
,Python 会报错,防止功能缺失:
class NetworkLogger(Logger):pass # 忘了写 log 方法logger = NetworkLogger() # TypeError: Can't instantiate abstract class NetworkLogger with abstract method log
- 如果开发者新写
-
新增日志方式更方便
- 以后要加 云日志、远程 API 日志 之类的,只需继承
Logger
并实现log()
,不会影响现有代码:
class CloudLogger(Logger):def log(self, msg):print(f"Sending '{msg}' to cloud storage...")
- 以后要加 云日志、远程 API 日志 之类的,只需继承
-
提高代码可读性,减少混乱
- 团队成员看到
Logger
抽象类,就知道所有日志类都有log()
方法,而不会有人随便起不同的方法名。
- 团队成员看到
总结
- 抽象类 让所有日志类的接口统一,防止命名混乱。
- 强制子类实现
log()
方法,防止开发者漏写关键功能。 - 以后要新增日志类型,只需要继承
Logger
并实现log()
方法,不影响其他代码。 - 调用方式一致,使用
process_logs(logger, msg)
处理不同日志,避免各种log_message()
、write_log()
、save()
的混乱。
在这里你可能又有一个疑问
是否可以理解成抽象类其实就是一个父类?
是的,可以理解成 “抽象类就是一个特殊的父类”,但是相比普通父类,它有以下 两点关键区别:
-
不能直接实例化(不能直接创建对象)
- 例如
Logger
只是个抽象概念,不能Logger()
直接用,而是用它的子类(ConsoleLogger
、FileLogger
)。
logger = Logger() # ❌ 报错:TypeError: Can't instantiate abstract class Logger
- 例如
-
必须让子类实现某些方法
- 抽象类里用
@abstractmethod
标记的方法,子类必须重写,否则 Python 不允许创建子类的实例:
class Logger(ABC):@abstractmethoddef log(self, msg):pass # 这个方法必须由子类实现
- 抽象类里用
普通父类 vs 抽象类
特性 | 普通父类 | 抽象类 |
---|---|---|
能否直接创建对象? | ✅ 可以 | ❌ 不能 |
是否强制子类实现方法? | ❌ 不强制 | ✅ 强制 |
简单来说:
- 普通父类更像是可以直接用的工具箱,你可以直接拿来创建对象。
- 抽象类更像是一张设计图,告诉子类“必须实现哪些方法”,但不能直接用。
如果只是提供通用功能(比如 super().__init__()
共享构造逻辑),用普通父类就够了。
如果是设计一个必须让子类实现某些功能的模板,那就用抽象类。
你可以把抽象类想象成“公司规定”——
“所有员工(子类)都必须打卡(实现
log()
方法)!”
“但是规定本身(Logger
抽象类)不能当员工。”
那么我们又如何从代码上区分一个类是抽象类还是普通的父类?
从代码上区分 抽象类 和 普通父类,主要看以下几个特征:
1. 是否继承 ABC
- 抽象类 必须继承
ABC
(Abstract Base Class),普通父类不需要。
from abc import ABC, abstractmethodclass AbstractClass(ABC): # ✅ 抽象类,继承 ABCpassclass NormalClass: # ❌ 普通父类,没有继承 ABCpass
2. 是否有 @abstractmethod
- 抽象类 至少有一个
@abstractmethod
装饰的方法,普通父类没有。
from abc import ABC, abstractmethodclass AbstractClass(ABC):@abstractmethoddef required_method(self):pass # 这个方法必须让子类实现class NormalClass:def normal_method(self):pass # 这个方法可选,子类不一定要实现
3. 能否直接实例化
- 抽象类 不能 直接实例化,普通父类可以。
abstract_obj = AbstractClass() # ❌ TypeError: 不能实例化抽象类
normal_obj = NormalClass() # ✅ 可以实例化普通父类
4. 是否强制子类实现某些方法
- 抽象类 强制 子类必须实现
@abstractmethod
方法,否则不能实例化子类。
class ConcreteClass(AbstractClass): # 继承抽象类passobj = ConcreteClass() # ❌ TypeError: 子类没实现 required_method,无法实例化
总结:快速判断方法
判断方法 | 普通父类 | 抽象类 |
---|---|---|
是否继承 ABC ? | ❌ 否 | ✅ 是 |
是否有 @abstractmethod ? | ❌ 没有 | ✅ 有 |
能否直接创建对象? | ✅ 可以 | ❌ 不行 |
子类是否必须实现某些方法? | ❌ 不强制 | ✅ 强制 |
如果一个类符合 继承 ABC
且有 @abstractmethod
,那它就是 抽象类!
否则,它就是 普通父类。
相关文章:

python中的抽象类在项目中的实际应用
抽象类在项目中的实际应用主要体现在 规范代码结构、强制子类实现某些方法、提供部分通用功能,让代码更稳定、易维护。 举个例子:数据校验器 假设你在做一个 用户输入校验系统,需要支持 数字校验、字符串校验 和 邮箱校验。如果不用抽象类&…...
New Game--(单调队列)
I - New Game 有一种新的游戏,Monocarp 想要玩。这个游戏使用一副包含 n 张牌的牌堆,其中第 i 张牌上写有一个整数 a_i。 在游戏开始时,Monocarp 可以在第一轮选择牌堆中的任意一张牌。在接下来的每一轮中,Monocarp 可以选择一张…...

mapbox V3 新特性,添加下雪效果
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象…...
无人机遥感在农林信息提取中的实现方法与GIS融合制图教程
遥感技术作为一种空间大数据手段,能够从多时、多维、多地等角度,获取大量的农情数据。数据具有面状、实时、非接触、无伤检测等显著优势,是智慧农业必须采用的重要技术之一。 一:综合态势分析 1.1 研究区及作物品种分析 ÿ…...

生物发酵展与2025生物医药创新技术与应用发展论坛同期盛大举办
近日,备受瞩目的生物发酵展与2025生物医药创新技术与应用发展论坛暨展览会宣布将同期盛大举办。这一消息标志着生物科技领域两大盛会的强强联合,将为全球生物科技与医药行业带来前所未有的交流与合作机遇。 生物发酵展作为生物科技领域的知名展会&#x…...

Jenkins 配置 Git Repository 五
Jenkins 配置 Git Repository 五 这里包含了 Freestyle project 任务类型 和 Pipeline 任务类型 关于 Git 仓库的配置,如下 不同的任务类型,只是在不同的模块找到 配置 Git 仓库 找到 Git 仓库配置位置之后,所有的任务类型配置都是一样的 …...
记录阿里云CDN配置
网站接入CDN全流程,共4步!-阿里云开发者社区 1、开通阿里云CDN服务 2、添加加速域名 3、验证域名归属权 4、域名添加CDN生成的CNAME解析 按照官网描述增加。细节点: 1. 域名和泛域名区别 2.开启https,要用nginx的证书,和项…...

mapbox 从入门到精通 - 目录
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀总目录1.1 ☘️ mapbox基础1.2 ☘️…...
mysql中general_log日志详解
介绍 1.记录范围:这个log里面会记录MySQL所有的SQL语句,不管是查询语句,还是DML语句,还是DDL语句,还是DCL语句,这些语句统统都会被记录在general log文件中。就连我们连接和断开MySQL数据库的这些语句。 2…...
算法与数据结构:从基础到深入
1. 数组 (Array) 定义 一组连续内存空间存储的相同类型元素的集合。特点:通过下标(索引)快速访问元素,但大小固定(静态数组)或可扩展(动态数组)。 核心操作 操作时间复杂度说明访…...

基于千兆5G网关的5G急救车方案
伴随5G网络的全面建成,5G技术的低延时、高速率、广接入等优势,为各行各业都带来了新一轮技术升级。在医疗救援方面,救护车是链接病患与医院的重要纽带,得益于5G物联网的融合应用,救护车也快速向联网化、信息化、智能化…...
【C#】的WPF或是WinForm实现Ctrl+ 的快捷键组合使用
在C#中,无论是WPF还是WinForms应用程序,处理快捷键(例如 Ctrl )通常涉及检测键盘输入并执行相应的命令或方法。 WPF 实现 在WPF中,可以通过设置一个控件的 InputBindings 属性来绑定快捷键。 <Window x:Class&qu…...

c语言样式主题 清爽风格 代码色彩 keil风格 适合单片机开发GD32 STM32等 cursor或者vscode 的settings.json文件
c语言样式主题 清爽风格 代码色彩 keil风格 适合单片机开发GD32 STM32等 cursor或者vscode 的settings.json文件 如上图,是不是和keil mdk很相近。 代码色彩,简单,配合 // 设置工作台主题为 Visual Studio 2017 Light - C 主题使用…...
DeepSeek API 调用 - Spring Boot 实现
DeepSeek API 调用 - Spring Boot 实现 1. 项目依赖 在 pom.xml 中添加以下依赖: <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></depe…...
图数据库Neo4j面试内容整理-节点(Node)
在图数据库中,节点(Node)是图结构中的基本构建块,代表实体或对象。节点通常用于存储数据模型中的主要对象,比如人、商品、地点等。在图数据库中,节点是通过标签(Label)来分类的,并且可以包含属性(Property)来描述它们的详细信息。 1. 节点的组成<...

使用verilog 实现 cordic 算法 ----- 旋转模式
1-设计流程 ● 了解cordic 算法原理,公式,模式,伸缩因子,旋转方向等,推荐以下链接视频了解 cordic 算法。哔哩哔哩-cordic算法原理讲解 ● 用matlab 或者 c 实现一遍算法 ● 在FPGA中用 verilog 实现,注意…...

2.14寒假
这几天复习的搜索把之前做过的题目看了一下。 解析:int dx[5]{0,0,1,0,-1}; 和 int dy[5]{0,1,0,-1,0};:这两个数组用于表示上下左右四个方向的偏移量,方便在 DFS 中访问相邻的元素。o 和 p 分别表示当前搜索位置的行和列。边界条件判断&…...
基于逻辑概率的语义信道容量(Semantic Channel Capacity)和语义压缩理论(Semantic Compression Theory)
基于逻辑概率的语义信道容量(Semantic Channel Capacity)和语义压缩理论(Semantic Compression Theory)是语义通信(Semantic Communication, SemCom)的核心研究方向,它们旨在优化通信效率&#…...

DeepSeek R1本地部署教程
尽管许多卖课博主声称能轻松运行满血版DeepSeek R1,但满血版R1模型参数高达671B,仅模型文件就需要404GB存储空间,运行时更需要约1300GB显存。 对于没有卡的普通玩家来说,运行的条件苛刻,且门槛极高。基于此࿰…...

CEF132编译指南 MacOS 篇 - 获取 CEF 源码 (五)
1. 引言 在完成了所有必要工具的安装和配置之后,我们正式进入获取 CEF132 源码的阶段。对于 macOS 平台,CEF 的源码获取过程需要特别注意不同芯片架构(Intel 和 Apple Silicon)的区别以及版本管理。本篇将作为 CEF132 编译指南系…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...

GraphQL 实战篇:Apollo Client 配置与缓存
GraphQL 实战篇:Apollo Client 配置与缓存 上一篇:GraphQL 入门篇:基础查询语法 依旧和上一篇的笔记一样,主实操,没啥过多的细节讲解,代码具体在: https://github.com/GoldenaArcher/graphql…...