Python父类调用子类实现的私有抽象方法报错,如何解决?
解决父类调用子类私有方法触发NotImplementedError的问题
问题原因
你遇到的问题根源是Python的**名称修饰(Name Mangling)**机制:当方法名以双下划线__开头时,Python会自动将其转换为_类名__方法名的格式。
- 父类A中的
__init_second会被转换为_A__init_second - 子类B/C中定义的
__init_second会被分别转换为_B__init_second和_C__init_second
因此,父类A的__init__方法调用的是自身的_A__init_second,而子类并没有重写这个被修饰后的方法,自然会触发NotImplementedError。
解决方案
方案一:使用受保护方法(推荐)
将双下划线开头的私有方法改为单下划线开头的受保护方法,同时结合抽象基类确保子类必须实现该方法:
from abc import ABC, abstractmethod class A(ABC): def __init__(self): self._init_first() self._init_second() def _init_first(self): # 实现通用初始化逻辑 pass @abstractmethod def _init_second(self): raise NotImplementedError() class B(A): def __init__(self): super().__init__() def _init_second(self): # B类专属初始化逻辑 print("执行B类的初始化逻辑") class C(A): def __init__(self): super().__init__() def _init_second(self): # C类专属初始化逻辑 print("执行C类的初始化逻辑") b = B() # 输出:执行B类的初始化逻辑 c = C() # 输出:执行C类的初始化逻辑
说明:
- 单下划线开头的方法是Python约定的受保护成员,不会被名称修饰,子类可以直接重写,父类调用时会自动匹配子类的实现。
- 继承
ABC并使用@abstractmethod,能强制子类必须实现_init_second,否则无法实例化子类,比单纯抛异常更严谨。
方案二:显式重写修饰后的方法名(不推荐)
如果一定要保留双下划线命名(不建议,破坏封装性),可以在子类中直接重写父类被名称修饰后的方法:
from abc import ABC, abstractmethod class A(ABC): def __init__(self): self.__init_first() self.__init_second() def __init_first(self): # do something pass @abstractmethod def __init_second(self): raise NotImplementedError() class B(A): def __init__(self): super().__init__() def _A__init_second(self): # 直接重写父类修饰后的方法名 # B类专属逻辑 print("执行B类的__init_second") class C(A): def __init__(self): super().__init__() def _A__init_second(self): # 直接重写父类修饰后的方法名 # C类专属逻辑 print("执行C类的__init_second") b = B() # 输出:执行B类的__init_second c = C() # 输出:执行C类的__init_second
说明:
这种方法依赖Python的名称修饰规则,代码可读性差,且如果父类名称修改,所有子类都需要同步修改方法名,维护成本高,不推荐使用。
内容的提问来源于stack exchange,提问作者Sanop
相关产品推荐
相关产品推荐

