Python中的抽象艺术:如何巧妙运用abc模块定义抽象基类

news2024/10/1 12:19:46

引言

在面向对象编程(OOP)中,抽象基类(Abstract Base Class, ABC)提供了一种定义接口的方式,它允许你指定子类必须实现的方法。通过这种方式,你可以创建一个清晰的类层次结构,明确哪些方法必须由继承自该基类的所有类实现。这种模式特别适用于框架设计或需要强制某些行为一致性的场景。

基础语法介绍

在Python中,abc模块提供了定义抽象基类所需的一切工具。首先,我们需要导入abc模块,并利用@abstractmethod装饰器来标记那些需要在子类中具体实现的方法。同时,可以通过继承ABC类来确保一个类成为抽象基类。

示例代码

import abc

class MyAbstractBaseClass(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def do_something(self):
        pass

class MyClass(MyAbstractBaseClass):
    def do_something(self):
        print("Doing something...")

try:
    obj = MyAbstractBaseClass()  # 这行会抛出TypeError,因为MyAbstractBaseClass不能实例化
except TypeError as e:
    print(e)

obj = MyClass()
obj.do_something()

这段简单的代码展示了如何定义一个抽象基类以及如何正确地继承和实现其抽象方法。

基础实例

假设我们正在开发一个图形库,需要定义一些基本的形状如圆形、矩形等。我们可以先创建一个抽象的Shape类,然后基于这个类去实现具体的形状。

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

    @abstractmethod
    def perimeter(self):
        pass

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14 * (self.radius ** 2)

    def perimeter(self):
        return 2 * 3.14 * self.radius

circle = Circle(5)
print(circle.area())  # 输出 78.5
print(circle.perimeter())  # 输出 31.4

进阶实例

当涉及到更复杂的系统时,可能需要多个抽象基类来共同协作。例如,在一个模拟银行系统的应用程序中,我们可能有Account, SavingsAccountCheckingAccount等类。这里可以使用多个抽象基类来更好地组织代码。

from abc import ABC, abstractmethod

class Account(ABC):
    @abstractmethod
    def withdraw(self, amount):
        pass

class SavingsAccount(Account):
    def withdraw(self, amount):
        # 实现取款逻辑...
        pass

class CheckingAccount(Account):
    def withdraw(self, amount):
        # 实现取款逻辑...
        pass

实战案例

在实际项目中,比如构建一个CMS(内容管理系统),我们可能会遇到需要多种类型的用户角色(如管理员、普通用户等)。通过定义抽象基类UserRole,我们可以确保每个角色都有必要的权限检查方法。

from abc import ABC, abstractmethod

class UserRole(ABC):
    @abstractmethod
    def has_permission(self, permission):
        pass

class AdminRole(UserRole):
    def has_permission(self, permission):
        # 实现管理员角色权限检查...
        return True if permission in ['admin', 'user'] else False

class UserRoleManager:
    def __init__(self, role: UserRole):
        self.role = role

    def perform_action(self, action, permission):
        if self.role.has_permission(permission):
            print(f"Action '{action}' allowed.")
        else:
            print(f"Action '{action}' not allowed.")

admin = AdminRole()
manager = UserRoleManager(admin)
manager.perform_action('create_user', 'admin')  # Action 'create_user' allowed.

扩展讨论

除了上述介绍的内容外,abc模块还支持许多其他特性,比如注册非子类作为兼容类型(register)等。这些功能使得Python在处理抽象概念时显得异常强大且灵活。对于有兴趣深入了解的朋友来说,官方文档总是最好的学习资源。

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

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

相关文章

免费送源码:Java+ssm+MySQL springboot健康医疗系统 计算机毕业设计原创定制

摘 要 随着我国经济迅速发展,人们对医疗管理的需求越来越大,各种健康医疗系统也都在被广泛应用,对于医疗管理的各种软件也是备受用户的喜爱,健康医疗系统被用户普遍使用,为方便用户能够可以随时进行健康医疗系统的数据…

【JAVA开源】基于Vue和SpringBoot的美容院管理系统

本文项目编号 T 055 ,文末自助获取源码 \color{red}{T055,文末自助获取源码} T055,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析5.4 用例设计 六、核…

NAL 网络提取层(Network Abstraction Layer)

1.NAL全称Network Abstract Layer, 即网络抽象层。 在H.264/AVC视频编码标准中,无论是存储还是网络传输,H264 原始码流是由一个接一个 NALU(NAL Unit) 组成,整个系统框架被分为两个层面:视频编码层面&#…

uniapp学习(003-1 vue3学习 Part.1)

零基础入门uniapp Vue3组合式API版本到咸虾米壁纸项目实战,开发打包微信小程序、抖音小程序、H5、安卓APP客户端等 总时长 23:40:00 共116P 此文章包含第11p-第p14的内容 文章目录 vue3使用介绍插值表达式例子时间戳随机数输出函数的值 ref响应式数据变量v-bind 绑…

PCL CropBox 过滤给定立方体内的点云数据

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 点云裁剪 2.1.2 可视化原始点云和裁剪后的点云 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接: PCL点云算法与项目实战案例汇总(长…

Python办公自动化案例:批量修改Word文件中的段落格式

案例:Python实现批量修改Word文件中的段落格式。 在处理大量Word文档时,经常需要批量修改这些文档的格式,比如统一段落格式,以提升文档的一致性和专业性。使用Python来实现这一任务可以极大地提高工作效率,特别是当涉及到数百或数千个文档时。Python通过第三方库如python…

【C#】CacheManager:高效的 .NET 缓存管理库

在现代应用开发中,缓存是提升性能和降低数据库负载的重要技术手段。无论是 Web 应用、桌面应用还是移动应用,缓存都能够帮助减少重复的数据查询和处理,从而提高系统的响应速度。然而,管理缓存并不简单,尤其是当你需要处…

《RabbitMQ篇》Centos7安装RabbitMQ

安装RabbitMQ 安装包网盘下载地址 链接:https://pan.baidu.com/s/1bG_nP0iCdAejkctFp1QztQ?pwd4mlw 先上传安装包到服务器(erlang-23.3.4.11-1.el7.x86_64.rpm和rabbitmq-server-3.9.16-1.el7.noarch.rpm)然后使用指令安装 # 安装 erlang r…

掌握 JVM 垃圾收集线程:简化 VM 选项

垃圾收集阶段对于任何 Java 应用程序都至关重要。主要目标是保持高吞吐量和低延迟之间的平衡。通过配置垃圾收集器,我们可以提高性能,或者至少推动应用程序朝着特定的方向发展。 垃圾收集周期越短越好。因此,分配给垃圾收集器的资源越多&…

昇思MindSpore进阶教程--下沉模式

大家好,我是刘明,明志科技创始人,华为昇思MindSpore布道师。 技术上主攻前端开发、鸿蒙开发和AI算法研究。 努力为大家带来持续的技术分享,如果你也喜欢我的文章,就点个关注吧 正文开始 昇腾芯片集成了AICORE和AICPU等…

C#自定义工具类-数组工具类

目录 数组工具类基本操作 1.排序:升序,降序 2.查找 1)查找最值:最大值,最小值 2)查找满足条件的单个对象 3)查找满足条件的所有对象 4)选取数组中所有对象的某一字段 完整代…

河南做网站与SEO:如何提升搜索引擎排名

河南做网站与SEO:如何提升搜索引擎排名 在当今数字化时代,越来越多的企业意识到互联网的重要性,特别是在河南这样一个快速发展的地区,建立一个优秀的网站已经成为企业发展的必要条件。而在建立网站的同时,SEO&#xff…

--- java数据结构 map set ---

java中map 和 set的底层实现是通过搜索树和哈希函桶来实现 搜索树 二叉搜索树有叫二叉排序树 他具有以下的特点 若存在左节点,那么他左节点的值一定小于根节点 若存在右节点,那么他右节点的值一定大于根节点 它的左右子树也是搜索树 对他进行中序…

leetcode热题100.最长公共子序列

题目 1143. 最长公共子序列 - 力扣(LeetCode) 给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。 一个字符串的 子序列 是指这样一个新的字符串:它是由原…

SOMEIP_ETS_143: SD_Request_non_existing_ServiceID

测试目的: 验证DUT能够拒绝一个请求不存在的服务ID(ServiceID)的SubscribeEventgroup消息,并以SubscribeEventgroupNAck作为响应。 描述 本测试用例旨在确保DUT遵循SOME/IP协议,当接收到一个请求不存在服务ID的Subs…

RS485串口通信:【图文详讲】

RS485,RS的意义为Recommended Standard的缩写,也就是推荐标准,是一种常用的半双工-异步-串行通信总线。半双工的意思就是两者通信时,同一时刻,只能由其中一方发送,另一方只能接收,不可以同时收发…

vue3 antdv3/4 Modal显示一个提示,内容换行显示。

1、官网地址: Ant Design Vue — An enterprise-class UI components based on Ant Design and Vue.js 2、显示个信息: Modal.info({title: This is a notification message,content: h(div, {}, [h(p, some messages...some messages...),h(p, some …

基于解压缩模块的JPEG同步重压缩检测论文学习

一、论文基本信息: 论文题目:基于解压缩模块的JPEG同步重压缩检测 作者:王金伟1 ,胡冰涛1 ,张家伟1 ,马 宾2 ,罗向阳3 (1.南京信息工程大学计算机学院、网络空间安全学院&#xf…

Linux-L11-查看本机ip地址

linux查看ip地址 查看自己的IP地址使用 ip 命令:使用 ifconfig 命令使用 hostname 命令:使用 nmcli 命令 查看某个特定接口的IP查看公网IP地址 在Linux系统中,查看自己的IP地址可以通过多种方式实现,这里提供几种常用的方法&#…

Stable Diffusion绘画 | LCM模型:实现秒出图

在过往,不管使用 SD 还是 MJ,生成一张图片起码要等上10秒。 而现在,有了 LCM 技术的加持,已经能做到秒出图,甚至是实时出图。 LCM(潜空间一致性模型) 是由 清华大学信息科学技术研究院 研发的大模型,它最…