Python中继承抽象类未实现抽象方法却未抛异常,原因何在?
嘿,这个问题我之前也踩过坑!咱们来一步步搞清楚为啥没触发你预期的异常:
核心原因拆解
1. 你可能根本没实例化ChildPizza类
抽象基类(ABC)的检查逻辑是懒加载的——它不会在你定义子类的时候就跳出来报错,只有当你尝试创建子类的实例(也就是执行pizza = ChildPizza()这种代码)的时候,才会去校验你有没有实现所有抽象方法。
如果你的代码只是停留在定义ChildPizza这一步,那Python完全不会有任何反应。试试给代码加一行实例化的代码:
from abc import ABCMeta, abstractmethod class BasePizza(object): __metaclass__ = ABCMeta @abstractmethod def get_radius(self): raise NotImplementedError("implement me in child class") class ChildPizza(BasePizza): pass # 加这行,马上就能看到你预期的异常! pizza = ChildPizza()
运行这段代码,你就会看到TypeError: Can't instantiate abstract class ChildPizza with abstract methods get_radius的报错,这才是正常的表现。
2. 你可能在Python 3环境下用了Python 2的写法
你的代码里用的是Python 2时代声明抽象基类的方式(__metaclass__ = ABCMeta),但在Python 3里,这种写法已经失效了!Python 3里要正确声明抽象基类,有两种方式:
方式一:直接继承ABC
这是最简洁的写法,ABC已经帮你内置了ABCMeta元类:
from abc import ABC, abstractmethod class BasePizza(ABC): @abstractmethod def get_radius(self): raise NotImplementedError("implement me in child class")
方式二:用metaclass关键字参数
如果你不想继承ABC,可以直接在类声明里指定元类:
from abc import ABCMeta, abstractmethod class BasePizza(object, metaclass=ABCMeta): @abstractmethod def get_radius(self): raise NotImplementedError("implement me in child class")
要是你在Python 3里还沿用Python 2的__metaclass__写法,BasePizza根本不会被识别成抽象基类,那ChildPizza就算没实现抽象方法,Python也不会管——哪怕你实例化它,也不会报错。
总结一下
- 如果你用的是Python 2:只要给
ChildPizza加个实例化操作,就能看到预期的异常; - 如果你用的是Python 3:先把
BasePizza的声明改成Python 3的正确写法,再实例化子类,就能触发异常啦。
内容的提问来源于stack exchange,提问作者Barka
相关产品推荐
相关产品推荐

