全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-19 8 分钟 ✍️ juanwangdev

Python 抽象基类 ABC

abc 模块提供抽象基类机制,强制子类实现特定方法,确保接口一致性。

基本用法

Python
from abc import ABC, abstractmethod


class Animal(ABC):
    "抽象基类"

    @abstractmethod
    def speak(self):
        "子类必须实现"
        pass

    @abstractmethod
    def move(self):
        "子类必须实现"
        pass


class Dog(Animal):
    def speak(self):
        return "汪汪"

    def move(self):
        return "跑"


class Cat(Animal):
    def speak(self):
        return "喵喵"

    def move(self):
        return "跳"


# 实例化子类
dog = Dog()
print(dog.speak())  # 汪汪

# 实例化抽象类会报错
# Animal()  # TypeError: Can't instantiate abstract class Animal

未实现抽象方法的错误

Python
class Bird(Animal):
    def speak(self):
        return "啾啾"

    # 未实现 move 方法


# Bird()  # TypeError: Can't instantiate abstract class Bird with abstract method 'move'

抽象属性

Python
from abc import ABC, abstractmethod


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

    @property
    @abstractmethod
    def name(self):
        "抽象属性"
        pass


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

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

    @property
    def name(self):
        return "圆形"


c = Circle(5)
print(c.area())  # 78.5
print(c.name)    # 圆形

抽象类方法与静态方法

Python
from abc import ABC, abstractmethod


class Plugin(ABC):
    @classmethod
    @abstractmethod
    def create(cls):
        "抽象类方法"
        pass

    @staticmethod
    @abstractmethod
    def info():
        "抽象静态方法"
        pass


class MyPlugin(Plugin):
    @classmethod
    def create(cls):
        return cls()

    @staticmethod
    def info():
        return "MyPlugin v1.0"


p = MyPlugin.create()
print(MyPlugin.info())  # MyPlugin v1.0

装饰器顺序:@classmethod / @staticmethod 必须在最外层。

注册虚拟子类

使用 register 将类注册为抽象基类的虚拟子类:

Python
from abc import ABC, abstractmethod


class MySequence(ABC):
    @abstractmethod
    def __getitem__(self, index):
        pass

    @abstractmethod
    def __len__(self):
        pass


# 注册内置类型为虚拟子类
MySequence.register(list)
MySequence.register(tuple)

# 类型检查生效
print(isinstance([1, 2, 3], MySequence))  # True
print(isinstance((1, 2), MySequence))     # True

subclasshook 自定义检查

Python
from abc import ABC


class ContainerLike(ABC):
    "自定义子类检查"

    @classmethod
    def __subclasshook__(cls, subclass):
        # 检查是否有 __contains__ 方法
        if hasattr(subclass, '__contains__'):
            return True
        return NotImplemented


# 不继承但符合协议
class MyContainer:
    def __contains__(self, item):
        return True


print(isinstance(MyContainer(), ContainerLike))  # True

collections.abc 模块

Python 内置多种抽象基类:

Python
from collections.abc import Sized, Iterable, Container, Sequence

# Sized:有 __len__ 方法
class MyList(Sized):
    def __init__(self, data):
        self.data = data

    def __len__(self):
        return len(self.data)


lst = MyList([1, 2, 3])
print(isinstance(lst, Sized))  # True
print(len(lst))                # 3

# 检查内置类型
print(isinstance([1, 2], Sized))      # True
print(isinstance("hello", Iterable))  # True
print(isinstance({1, 2}, Container))  # True
print(isinstance((1, 2), Sequence))   # True

常用抽象基类

基类要求方法
Sized__len__
Iterable__iter__
Container__contains__
Sequence__getitem__, __len__
Mapping__getitem__, __iter__, __len__
Set__contains__, __iter__, __len__

接口继承示例

Python
from abc import ABC, abstractmethod


class Database(ABC):
    "数据库接口"

    @abstractmethod
    def connect(self):
        pass

    @abstractmethod
    def disconnect(self):
        pass

    @abstractmethod
    def execute(self, query):
        pass

    @abstractmethod
    def fetch(self):
        pass


class MySQLDatabase(Database):
    def connect(self):
        print("连接 MySQL")

    def disconnect(self):
        print("断开 MySQL")

    def execute(self, query):
        print(f"执行: {query}")

    def fetch(self):
        return ["row1", "row2"]


class PostgreSQLDatabase(Database):
    def connect(self):
        print("连接 PostgreSQL")

    def disconnect(self):
        print("断开 PostgreSQL")

    def execute(self, query):
        print(f"执行: {query}")

    def fetch(self):
        return ["row1", "row2"]


# 统一接口调用
def use_database(db: Database):
    db.connect()
    db.execute("SELECT * FROM users")
    print(db.fetch())
    db.disconnect()


use_database(MySQLDatabase())
use_database(PostgreSQLDatabase())

抽象基类与鸭子类型

Python
# 鸭子类型:只要有方法就能用
class DuckTyped:
    def speak(self):
        return "叫声"


def make_sound(animal):
    # 不检查类型,直接调用
    return animal.speak()


make_sound(DuckTyped())  # 声

# 抽象基类:强制接口
def make_sound_with_abc(animal: Animal):
    # 类型检查确保有 speak 方法
    return animal.speak()


make_sound_with_abc(Dog())      # 汪汪
# make_sound_with_abc(DuckTyped())  # DuckTyped 不是 Animal 子类
方式特点
鸭子类型不需要继承,灵活但无约束
抽象基类强制接口,有类型检查保障

混合使用抽象方法与普通方法

Python
from abc import ABC, abstractmethod


class Vehicle(ABC):
    "抽象基类可以有普通方法"

    @abstractmethod
    def start(self):
        pass

    @abstractmethod
    def stop(self):
        pass

    def horn(self):
        "普通方法:所有子类共享"
        return "鸣笛"


class Car(Vehicle):
    def start(self):
        print("启动汽车")

    def stop(self):
        print("停止汽车")


car = Car()
car.start()
car.horn()  # 鸣笛(继承普通方法)

要点总结

要点说明
ABC抽象基类父类
@abstractmethod定义抽象方法
实例化限制未实现所有抽象方法无法实例化
register()注册虚拟子类
__subclasshook__自定义类型检查逻辑

抽象基类提供接口约束,与鸭子类型互补,适合需要类型检查和强制接口的场景。

D:\git2\jwdev\articles\PYTHON\进阶\面向对象编程\抽象基类ABC.md

📝 发现内容有误?点击此处直接编辑

← 上一篇 Python 属性访问控制
下一篇 → Python 描述符协议
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库