Python子类调用父类双下划线类私有方法报错原因及解决方案
报错根因
触发该错误是Python的名称修饰(Name Mangling)机制的预期行为:
类定义中所有以双下划线__开头、且不以双下划线结尾的方法/属性,会被Python在编译阶段自动重命名为_当前类名__原标识符的格式,重命名规则仅和标识符定义/调用所在的类绑定,不受继承关系影响。
你代码中的__search方法定义在父类A中,实际存储的方法名是_A__search;但在子类B的方法内写self.__search()时,Python会基于当前上下文类B做名称转换,尝试查找不存在的_B__search方法,因此抛出属性不存在的错误。
继承场景下的调用方式
方式1:直接调用名称修饰后的真实方法名
可以直接写重命名后的完整方法名完成调用,注意该写法属于直接访问父类内部实现,父类如果调整私有方法命名会直接导致代码失效:
class B(A): def display(self): # 显式指定父类修饰后的方法名 res = self._A__search() return res
方式2:父类暴露非私有调用入口(推荐)
双下划线标识符的设计初衷,就是避免子类无意覆盖父类的内部实现逻辑,本身就不设计为给子类直接调用。如果父类的某段逻辑需要被子类复用,应该在父类中提供单下划线开头的保护级方法做转发,符合Python的封装约定:
class A: def __init__(self, a): self.a = a def __search(self): return self.a # 暴露保护级方法给子类调用 def _search(self): return self.__search() def display(self): print(self.a) class B(A): def display(self): res = self._search() return res cB = B(2) cB.display() # 正常返回2
注意:Python不存在强制的私有访问限制,双下划线机制仅用于避免命名冲突、防止子类意外覆写父类内部成员,不是安全访问控制手段。按照社区约定,需要给子类/外部可控访问的内部成员,应该用单下划线
_开头标记为保护成员,不使用双下划线命名。
内容的提问来源于stack exchange,提问作者codeBarer
相关产品推荐
相关产品推荐

