Python的abc模块通过运行时实例化检查强制抽象约束,而非编译时接口定义;必须用@abstractmethod显式标记至少一个方法,且子类须完整实现所有抽象方法,否则实例化时抛出TypeError。

Python 的 abc 模块不是用来“定义接口”的替代品,而是为类提供运行时强制的抽象约束 —— 用错场景或漏掉关键步骤,ABC 就形同虚设。
为什么继承 ABC 后仍能实例化?
常见错误:只写 class Shape(ABC):,但没加任何 @abstractmethod,或者忘了在子类中实现所有抽象方法。Python 不会在类定义时检查,而是在尝试实例化子类时才抛出 TypeError: Can't instantiate abstract class ...。
- 必须至少有一个
@abstractmethod(包括@abstractproperty、@abstractclassmethod等)才能触发实例化拦截 - 子类若未实现全部抽象方法(哪怕只差一个),实例化时立刻报错,不会等到调用时才失败
-
ABC本身不能被实例化,但它的子类只要满足“所有抽象方法都被具体实现”,就能正常创建对象
@abstractmethod 必须修饰什么?
它只能修饰类中定义的可调用成员:普通实例方法、@classmethod、@staticmethod、@property。不能修饰模块级函数、变量,也不能直接修饰 __init__(但可以修饰它 —— 只是不推荐,因为初始化逻辑通常应由子类自己控制)。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 修饰
__init__是合法的,但会导致子类必须重写构造逻辑,容易破坏封装;更稳妥的做法是把校验逻辑放在抽象方法里,比如validate_config() - 修饰
@property时,子类需用@property覆盖,不能用普通属性赋值代替 - 如果想让某个方法“可选实现”,就不要加
@abstractmethod,而应在文档或类型提示(如Optional[Callable])中说明
如何让非直接子类也受约束?
默认情况下,只有显式继承自 ABC 的类才会被检查。若想让“鸭子类型”也纳入规范(例如第三方类),要用 register() 方法注册,但注意:注册后该类不会获得任何抽象方法,仅用于 isinstance() / issubclass() 判断。
立即学习“Python免费学习笔记(深入)”;
-
Shape.register(Circle)后,isinstance(Circle(), Shape)返回True,但Circle()仍可被实例化,且不强制实现area() - 注册无法替代真正的继承,也不触发方法检查 —— 它只是给类型系统打个标记
- 真正需要强契约时,坚持用继承 +
@abstractmethod;注册仅适合已有类无法修改源码、又需参与统一类型判断的场景
最容易被忽略的是:抽象方法签名(参数名、数量、默认值)在子类中必须严格一致,否则虽能实例化,但运行时可能因参数不匹配而崩溃 —— abc 不做签名检查,得靠测试或类型检查器(如 mypy)补位。

















