请选择 进入手机版 | 继续访问电脑版
查看: 8629|回复: 3

Python抽象类实现详解:abc模块与abstractmethod

[复制链接]
发表于 2026-9-2 11:00:00 | 显示全部楼层 |阅读模式
在Python的面向对象编程中,抽象类是一种特殊的基类:它本身不能被实例化,核心作用是规定子类必须实现哪些方法。Python标准库提供了abc模块来支持抽象类,其中最核心的两个要素是ABC基类和@abstractmethod装饰器。

最简单的一个抽象类例子如下:所有继承ABC的子类,只要包含@abstractmethod装饰的方法,就必须在子类中实现这些方法,否则子类仍然无法实例化。
  1. from abc import ABC, abstractmethod
  2. class Animal(ABC):
  3.     @abstractmethod
  4.     def speak(self):
  5.         """子类必须实现这个方法"""
  6.         pass
  7. # animal = Animal()  # TypeError: 不能实例化抽象类
  8. class Dog(Animal):
  9.     def speak(self):
  10.         print("Woof!")
  11. dog = Dog()
  12. dog.speak()  # Woof!
复制代码

实际开发中,抽象类往往不止一个抽象方法。来看一个更完整的几何图形示例,它同时定义了area和perimeter两个抽象方法,并且提供了一个普通方法describe给子类直接复用。
  1. from abc import ABC, abstractmethod
  2. class Shape(ABC):
  3.     @abstractmethod
  4.     def area(self):
  5.         """计算面积"""
  6.         pass
  7.     @abstractmethod
  8.     def perimeter(self):
  9.         """计算周长"""
  10.         pass
  11.     def describe(self):
  12.         """普通方法,子类可直接使用"""
  13.         print(f"这是一个图形,面积: {self.area()}, 周长: {self.perimeter()}")
复制代码

这里有几个要点需要记住:

1. 继承ABC的类就是抽象类。
2. 被@abstractmethod标记的方法是抽象方法,子类必须实现。
3. 抽象类中可以同时包含普通方法,这些方法提供默认实现,子类可以直接继承使用。
4. 抽象类本身不能创建实例。

除了方法,抽象属性同样可以被强制要求。比如员工类中,可以要求所有子类必须提供一个salary属性,并且该属性以属性的方式访问,而不是方法调用。
  1. from abc import ABC, abstractmethod
  2. class Employee(ABC):
  3.     @property
  4.     @abstractmethod
  5.     def salary(self):
  6.         """子类必须实现 salary 属性"""
  7.         pass
  8. class FullTimeEmployee(Employee):
  9.     def __init__(self, monthly_salary):
  10.         self._monthly_salary = monthly_salary
  11.     @property
  12.     def salary(self):
  13.         return self._monthly_salary
  14. emp = FullTimeEmployee(10000)
  15. print(emp.salary)  # 10000
复制代码

抽象属性实现时有两个关键点:@abstractmethod负责声明“这是子类必须实现的抽象成员”;@property保证子类实现后可以通过emp.salary这样的属性访问方式取值。装饰器顺序不能写反,@property必须在@abstractmethod的上面,否则会报错。

如果子类只实现了部分抽象方法,那么这个子类本身仍然是一个抽象类,依然不能实例化。例如Rectangle类继承了Shape,实现了area,但没有实现perimeter:
  1. class Rectangle(Shape):
  2.     def __init__(self, width, height):
  3.         self.width = width
  4.         self.height = height
  5.     def area(self):
  6.         return self.width * self.height
  7.     # 忘记实现 perimeter 方法
  8.     # rect = Rectangle(3, 4)  # TypeError: 不能实例化抽象类 Rectangle
复制代码

这种设计在大型项目中特别有用:抽象类相当于一份“接口契约”,强制所有子类按照统一的结构实现关键行为,避免因为遗漏方法而在运行时才暴露问题。配合Python的abc模块,可以在类创建阶段就拦截错误,让代码结构更清晰、更安全。
回复

使用道具 举报

发表于 2026-9-2 19:00:00 | 显示全部楼层

Re: Python抽象类实现详解:abc模块与abstractmethod

感谢楼主分享,写得很清晰。我正好最近也在用abc,看完觉得几个关键点都说到了,特别是装饰器顺序和抽象属性那块。之前我总把@abstractmethod放上面,结果报错半天,现在明白一定要@property在外层。 另外楼主提到“部分实现仍然是抽象类”这点很实用,实际项目里确实经常用这个特性做中间层,先实现一部分公共逻辑,再把可变部分留给叶子子类。 我觉得如果能把抽象方法配合类型注解也提一下就更好了,比如加`-> float`之类的,对于接口约束会更明确。总之对新手理解“接口契约”这个概念很有帮助,学习了。
回复 支持 反对

使用道具 举报

发表于 2026-9-2 19:05:00 | 显示全部楼层

Re: Python抽象类实现详解:abc模块与abstractmethod

感谢分享,写得很清楚!之前一直对抽象属性那块的装饰器顺序有点懵,看到“@property必须在@abstractmethod上面”这个提醒一下就明白了。抽象类确实像一份“契约”,尤其在团队协作里,能让接手的人少踩很多坑。刚试了下那个 Shape 的例子,漏实现真的会直接报错,省得运行到一半才发现问题。收藏了,以后写基类时照着这个结构来。
回复 支持 反对

使用道具 举报

发表于 2026-9-2 19:10:00 | 显示全部楼层

Re: Python抽象类实现详解:abc模块与abstractmethod

楼主写得很清楚,尤其是装饰器顺序那个坑,之前自己写抽象属性的时候确实被报错搞懵过,看到这里就明白了。 个人感觉abc模块最爽的一点就是能把“设计约束”提前到类创建阶段暴露,而不是等程序跑到某个子类实例方法时才报AttributeError。像Shape那种带普通方法describe的写法,实际项目中复用起来相当顺手。 另外补充一个自己用过的点:如果子类实现了全部抽象方法,但在实例化前还想再检查一些额外条件,可以用`__init_subclass__`配合,不过这样会稍微绕一点。对于刚接触抽象类的同学来说,楼主帖子里的几个例子已经覆盖了最常见的用法,照着敲一遍基本就能上手了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-9-13 07:40 , Processed in 0.022091 second(s), 17 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部