当前位置:首页>python>Python继承小知识:双下划线私有方法为什么不怕子类重写?

Python继承小知识:双下划线私有方法为什么不怕子类重写?

  • 2026-10-11 06:41:24
Python继承小知识:双下划线私有方法为什么不怕子类重写?
在学习Python面向对象继承时,会遇到一个疑惑:父类普通方法会被子类同名方法覆盖,但如果把父类方法写成双下划线__xxx私有形式,子类就算写一模一样名字的方法,也完全覆盖不了父类内部调用,今天拆开底层原理一次性讲清楚。

一、先看普通方法:子类可以轻松重写覆盖

示例代码

运行结果:

foo from son

底层原理

1.Son子类继承Base父类,并重写了同名foo方法; 

2.执行s.test()时,会走到父类的test函数,内部执行self.foo();

3.Python 查找方法规则:实例自身 → 子类 Son → 父类 Base; 

4.self是子类 Son 的实例,优先找到子类重写后的foo方法执行,这就是面向对象的多态特性; 

5.重点:普通方法不会改名,父类、子类的方法都叫foo,子类同名会直接覆盖调用入口。

二、双下划线私有方法:子类永远无法覆盖父类内部调用

示例代码

运行结果

foo from base

核心底层机制:名称改写

Python有一条语法规则:以双下划线__开头、不以双下划线结尾的方法/属性,编译阶段会自动重命名改名公式:__方法名 → _当前类名__方法名

执行流程拆解

1. s.test()调用从父类继承来的test方法; 

2. 方法内代码早已被固定改写为self._Base__foo(); 

3. 程序只会去寻找名为_Base__foo的方法,只会执行父类内部定义的私有逻辑; 

4.子类写的__foo本质是另一个全新方法_Son__foo,完全不会干扰父类内部逻辑,实现父类核心方法不被子类篡改。

三、验证:打印实例属性字典,看清真实方法名

我们可以打印实例/类的命名空间,直观看到两个方法名字完全不一样:

输出里能清晰看到:

父类Base存储的私有方法:_Base__foo
子类Son存储的私有方法:_Son__foo

两个方法名完全独立,自然不存在重写覆盖一说。

四、总结

1.无下划线普通方法方法名称不会被改写,子类定义同名方法后,父类里self.方法()会动态匹配子类重写方法,支持多态。

2.双下划线__xxx私有方法编译阶段触发名称改写,自动拼接当前类名前缀;父类内部调用self.__xxx会被固定翻译为self._父类名__xxx,只会执行父类自身私有方法;子类的__xxx只会生成_子类名__xxx,和父类方法互不干扰,子类无法篡改父类内部逻辑。

补充小提示

Python的双下划线私有只是语法模拟私有,并非真正强制不可访问。如果硬要在外部调用父类私有方法,可以手动使用改写后的真实名称:s._Base__foo()

日常开发不推荐这种写法,会破坏封装性。

最新文章

随机文章