装饰器 · abstractmethod

0. 一句话定位

维度 内容
作用对象 类方法
使用场景 抽象
来源 标准库 abc.abstractmethod
语法形式 @abstractmethod(类须继承 ABC

段末注释:ABC(Abstract Base Class,ABC) 抽象基类,定义接口契约,不能直接实例化(含未实现抽象方法时)。

1. 做什么

装饰基类中的方法为「抽象」:子类必须覆盖实现,否则子类仍无法实例化;调用未实现的抽象方法会抛 TypeError

2. 重点参数

参数 类型 默认值 作用 配置建议
func callable 被标记方法 方法体可 passraise NotImplementedError

常与 @classmethod@property@staticmethod 组合(抽象方法本身也可带这些装饰器,见文档)。

3. 最小可运行示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from abc import ABC, abstractmethod

class Storage(ABC):
@abstractmethod
def save(self, data: bytes) -> None:
pass

@abstractmethod
def load(self) -> bytes:
pass

class MemoryStorage(Storage):
def __init__(self):
self._buf = b""

def save(self, data: bytes) -> None:
self._buf = data

def load(self) -> bytes:
return self._buf

store = MemoryStorage()
store.save(b"ok")
print(store.load()) # b'ok'

# Storage() # TypeError: Can't instantiate abstract class

4. 常见变体

抽象 @property

1
2
3
4
5
class Shape(ABC):
@property
@abstractmethod
def area(self) -> float:
pass

抽象 @classmethod

1
2
3
4
5
class Plugin(ABC):
@classmethod
@abstractmethod
def name(cls) -> str:
pass

5. 适用 / 不适用

适用

  • 插件、策略、存储后端等多实现统一接口
  • 框架要求子类必须实现特定钩子

不适用

  • 只有单一实现、无扩展点 → 普通类即可
  • 鸭子类型足够、不需强制继承 → Protocol(typing.Protocol

6. 易踩坑

  • 忘记继承 ABC,仅 @abstractmethod 不会阻止实例化
  • 子类实现了方法但签名不兼容仍可能运行时才发现
  • 抽象类可定义具体方法,供子类复用
  • @abstractmethod@property 顺序:Python 3.3+ 要求 @property 在外、@abstractmethod 在内(或见官方组合示例)

7. 近邻替代

替代 何时用
typing.Protocol 结构化子类型,不强制继承
NotImplementedError 轻量提示,无实例化约束
zope.interface 更重的接口体系

8. 参考

-------------本文结束感谢您的阅读-------------