Python中定义抽象基类
What
python中定义可以定义抽象类,和Java中的抽象类是一样的,不能被直接实例化,而是作为一个基类,主要用于定义一组接口规范,接口的实现在继承其的子类中完成,并且要求子类必须实现定义的所有接口,和Java一样如何子类未完全实现父类中的所有接口,那么这个子类也会被定义成为一个抽象类,不能直接实例化。
Why
- 强制接口一致性
- 实现多态性
- 促进代码重用
- 模板化编程
总之就是好处多多
How
定义抽象类主要有两种方法一种是通过继承ABC类,另一种是直接使用ABCMeta作为元类。
还可以结合使用 @abstractmethod 和 @abstractproperty(Python 3.3 及以上版本推荐使用 @property + @abstractmethod)来定义抽象方法和属性。
下面将依次介绍这两种方法。
继承ABC类
最常用、最简洁的方式,适用于绝大多数情况。只需要让自己的抽象类去继承abc.ABC即可,并使用@abstractmethod装饰器标记应该被子类实现的方法。
from abc import ABC, abstractmethod
class MyabstractClass(ABC):
@abstractmethod
def my_method(self):
pass
@property
@abstractmethod
def my_property(self):
pass
使用ABCMeta元类
from abc import ABCMeta, abstractmethod
class MyAbstractClass(metaclass=ABCMeta):
@abstractmethod
def my_method(self):
pass
@property
@abstractmethod
def my_property(self):
pass
- @abstractmethod:用于装饰普通方法,表明该方法是抽象的,所有非抽象子类都必须实现它。
- @property + @abstractmethod:用于定义抽象属性,确保子类提供具体的属性实现。
静态方法和类方法
除了普通的实例方法外,也可以定义抽象的静态方法和类方法。通过组合@abstractmethod 和 @staticmethod 或 @classmethod 来完成。
from abc import ABC, abstractmethod
class AbstractBaseClass(ABC):
@abstractmethod
@staticmethod
def static_method():
"""这是一个抽象静态方法"""
pass
@abstractmethod
@classmethod
def class_method(cls):
"""这是一个抽象类方法"""
pass
注册虚拟子类
有时可能想要声明某个类实现了特定接口,但并不直接继承自那个抽象基类。这时可以使用 register() 方法来注册一个“虚拟子类”。
from abc import ABC, abstractmethod
class PluginBase(ABC):
@abstractmethod
def load(self, input):
pass
class LocalPlugin:
def load(self, input):
return input.read()
PluginBase.register(LocalPlugin) # 注册 LocalPlugin 为 PluginBase 的虚拟子类
# 测试是否成功注册
print(issubclass(LocalPlugin, PluginBase)) # 应该输出 True
local_plugin = LocalPlugin()
print(isinstance(local_plugin, PluginBase)) # 应该输出 True
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2023-12-14 Codeforces Round 787 (Div. 3)D. Vertical Paths
2022-12-14 洛谷P1990