Python中为何能在类方法内调用其他同基类对象的私有方法?
你的核心误解在于对Python**名称修饰(Name Mangling)**作用范围的理解——你以为类的内部方法调用其他对象的私有方法属于“类外部”操作,但实际上,名称修饰的转换是在定义该方法的类的作用域内生效的,而change_others_name是Parent类的方法,属于Parent类的内部作用域,所以这里的调用会被Python自动处理。
具体原理拆解
当你在Parent类中定义__change_self_name时,Python会自动把这个方法名修改为_Parent__change_self_name(这就是名称修饰),所有在Parent类内部出现的__change_self_name都会被替换成这个修饰后的名称。
所以在change_others_name方法里的代码:
other_object.__change_self_name()
实际上会被Python自动转换成:
other_object._Parent__change_self_name()
而b_child是Child_2的实例,它继承自Parent类,所以它的实例中存在被修饰后的_Parent__change_self_name方法,自然就能调用成功。
对比报错的原因
你尝试在全局作用域调用a_child.__private_method_parent()时,因为这是在Parent类的外部,Python不会自动做名称修饰,所以直接查找__private_method_parent这个名称,而它已经被修饰成_Parent__private_method_parent,因此会报错。如果改成a_child._Parent__private_method_parent()就能正常执行。
总结
Python的私有方法(以双下划线开头)并非完全禁止外部访问,而是通过名称修饰来避免意外的名称冲突。只要是在定义该私有方法的类的内部作用域中,无论是操作自身实例还是其他同基类实例,Python都会自动处理名称修饰,从而可以调用到对应的方法;而在类外部则需要手动使用修饰后的名称才能访问。
内容的提问来源于stack exchange,提问作者Mighty God Loki

