Python抽象方法强制实现疑问:未实现抽象方法的子类可实例化?
为什么未实现抽象方法的子类能被实例化?
这个问题的核心有两个关键点,咱们一步步拆解:
1. 抽象类的写法在Python3中不生效
你用了__metaclass__ = abc.ABCMeta来定义抽象类,这是Python2中的写法。在Python3中,这种方式已经被废弃,正确的抽象类定义应该是通过metaclass参数指定:
# Python3 正确写法 import abc class Animal(abc.ABC): # 或者 class Animal(object, metaclass=abc.ABCMeta): def __init__(self, species): self._species = species def get_species(self): return self._species @abc.abstractmethod def eat(self): pass
如果你在Python3中运行你当前的代码,__metaclass__属性不会被识别,Animal类根本不是抽象类——自然也就不会强制子类实现eat()方法,所以Slug能正常实例化。
2. 你的Slug类构造函数定义错误
另外,你写的Slug类里的构造函数有两个明显错误:
- 方法名写错了:应该是
__init__(前后各两个下划线),你写成了__init(只有一个结尾下划线),这导致这个方法根本不是构造函数,实例化Slug时会直接调用父类的__init__。 super()的调用完全错误:super(species)不符合语法规范,正确的写法在Python2中是super(Slug, self).__init__(species),Python3中可以简化为super().__init__(species)。
不过这个构造函数的错误并不会导致抽象类约束失效,只是会让你的Slug类无法自定义初始化逻辑而已。
验证一下
如果你把代码改成Python3的正确抽象类写法,同时修正Slug的构造函数,再尝试实例化未实现eat()的Slug,就会触发预期的错误:
import abc class Animal(abc.ABC): def __init__(self, species): self._species = species def get_species(self): return self._species @abc.abstractmethod def eat(self): pass class Slug(Animal): def __init__(self, species): super().__init__(species) def run(self): print("running") # 未实现eat() sl = Slug("slug") # 这里会报错: TypeError: Can't instantiate abstract class Slug with abstract methods eat
这样就符合你一开始理解的“子类必须实现抽象方法否则无法实例化”的规则了。
内容的提问来源于stack exchange,提问作者Ziqi
相关产品推荐
相关产品推荐

