You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python子类如何访问父类的双下划线(dunder)方法?

Python子类能否访问父类的双下划线方法?

问题描述

我定义了如下类结构:

class Parent(object):
    def __init__(self, x):
        self.x = x
    
    def __add(self,y):
        return self.x + y
    
    def addition(self,y):
        return self.__add(y)

class Children(Parent):
    
    def add(self,y):
        return self.__add(y)

实例化后,Parent和Children的addition方法都能正常调用:

p = Parent(2)
p.addition(4)  # 正常运行

c = Children(5)
c.addition(4)  # 正常运行

但以下调用都会抛出AttributeError:

p.__add(5)  # 报错:'Parent' object has no attribute '__add'
c.add(4)    # 报错:'Children' object has no attribute '_Children__add'

其中第一种报错符合预期,但子类无法访问父类的__add方法让我困惑。实际场景中,我的父类包含一个__check_password方法,希望设为“私有”,同时能让多个子类调用这个方法。

原因分析

Python中,以双下划线__开头的方法会触发**名称修饰(Name Mangling)**机制:Python解释器会自动将这类方法重命名为_类名__方法名的格式。比如Parent类中的__add会被重命名为_Parent__add,而在Children类中调用self.__add时,Python会去寻找_Children__add,但这个方法并不存在,所以报错。

这种机制的目的是避免子类意外覆盖父类的私有方法,确保父类的内部实现不被子类破坏。

解决方案

方案1:使用单下划线作为“保护”方法(推荐)

Python中没有真正的私有方法,单下划线_开头的方法是约定俗成的“保护方法”——外部代码不应该直接调用,但子类可以正常访问。把父类的方法改成单下划线开头即可:

class Parent(object):
    def __init__(self, x):
        self.x = x
    
    def _add(self,y):  # 改为单下划线
        return self.x + y
    
    def addition(self,y):
        return self._add(y)

class Children(Parent):
    def add(self,y):
        return self._add(y)  # 子类直接调用

对应到你的实际场景,把__check_password改成_check_password,子类就能直接调用,同时外部代码也会遵循约定不随意调用这个方法。

方案2:直接调用被修饰后的方法(不推荐)

如果你坚持使用双下划线,可以在子类中直接调用父类被修饰后的方法名_Parent__add:

class Children(Parent):
    def add(self,y):
        return self._Parent__add(y)  # 直接调用重命名后的方法

但这种方式不推荐,因为它破坏了封装性,一旦父类的类名修改,子类中的调用代码也需要同步修改,维护成本高。

方案3:父类提供公共/保护接口封装私有方法

如果父类的双下划线方法必须保留,可以在父类中提供一个保护级别的接口方法,让子类通过这个接口调用私有方法:

class Parent(object):
    def __init__(self, x):
        self.x = x
    
    def __add(self,y):
        return self.x + y
    
    def addition(self,y):
        return self.__add(y)
    
    def _call_add(self, y):  # 提供给子类的保护接口
        return self.__add(y)

class Children(Parent):
    def add(self,y):
        return self._call_add(y)  # 子类调用保护接口

内容的提问来源于stack exchange,提问作者FraSchelle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 19:25:23