为何Python中含abstractmethod的类未继承ABC仍可实例化?
问题解答:未继承ABC的类含@abstractmethod仍可实例化的原因
这不是Python的bug,核心是你对@abstractmethod与ABCMeta元类的协作逻辑理解有偏差,以下是具体解释:
1. @abstractmethod的本质与生效条件
@abstractmethod装饰器的作用仅仅是给被装饰的方法打上一个抽象标记(添加__isabstractmethod__ = True属性),但它本身不会阻止类的实例化。只有当类的元类是ABCMeta(或其子类,比如通过继承ABC类间接使用ABCMeta)时,Python才会在类定义阶段和实例化阶段检查抽象方法的实现情况:
- 类定义时,
ABCMeta会收集所有带抽象标记的方法; - 实例化时,
ABCMeta会校验是否所有抽象方法都被实现,未实现则抛出TypeError。
而默认的元类type(即未继承ABC的类使用的元类)完全不会处理这个抽象标记,所以即便类里有@abstractmethod装饰的方法,依然可以正常实例化。
2. 纠正你的两点理解
- 理解1错误:元类不是
ABCMeta时,@abstractmethod装饰器会被Python正常接受,只是不会触发抽象类的实例化校验逻辑; - 理解2错误:未继承
ABC的类,即便包含@abstractmethod装饰的方法,也能被实例化,因为没有对应的元类来执行校验。
3. 结合你的代码示例分析
TestClassOne没有继承ABC,使用默认元类type,Python不会检查test_method的抽象标记,因此test_object_one = TestClassOne()可以正常执行,无报错;TestClassTwo继承了ABC,元类变为ABCMeta,实例化时会校验抽象方法是否实现,由于test_method未被实现,所以抛出TypeError: Can't instantiate abstract class TestClassTwo with abstract method test_method,这完全符合官方文档的描述。
内容的提问来源于stack exchange,提问作者CallMeStag
相关产品推荐
相关产品推荐

