Python类中私有(双下划线)方法解析及类内外部调用差异
Python双下划线方法解析相关问题解答
1. Python如何解析类中的私有(双下划线)方法?
首先得明确:Python里的双下划线方法并不是严格意义上的“私有方法”,它是靠**名称修饰(name mangling)**这个机制来实现类似私有效果的。具体过程是这样的:
- 当你在类内部定义一个以双下划线开头的方法(比如
__is),Python解释器会偷偷把这个方法的名字改成_类名__方法名的格式。拿你例子里的Foo类来说,__is会被重命名为_Foo__is,这个是存储在类属性里的真实名称。 - 当你在类的内部(比如类的方法里、类体的其他代码中)引用这个双下划线方法时,Python会自动帮你把
__is转换成_Foo__is,所以你写self.__is()或者Foo.__is()的时候,实际调用的是那个重命名后的方法,自然能成功解析。 - 但到了类外部,Python就不会帮你做这个转换了——你直接写
Foo.__is(),它就真的去类里找叫__is的方法,可实际上这个名字根本不存在,所以就会报错。
2. 为什么类内调用Foo.__is()成功,类外却失败?
咱们拿你给的代码来拆解:
class Foo(object): @staticmethod def __is(): print('__is') def m(self): Foo.__is() # 可执行
核心原因就是代码所在的作用域不同:
- 在
m方法内部,这段代码属于Foo类的定义作用域。当Python解析Foo.__is的时候,它能识别出这是在类内部引用双下划线开头的名称,于是自动触发名称修饰的转换——把__is替换成_Foo__is,所以实际执行的是Foo._Foo__is(),而这个方法确实存在,调用自然成功。 - 当你在类定义完成后,在类外部调用
Foo.__is()时,代码处于全局作用域(或者类外部的其他作用域),Python不会对__is做任何名称转换,它直接去Foo类的属性里找名为__is的方法,但真实存在的是_Foo__is,所以肯定会抛出AttributeError,提示找不到这个方法。
说白了,名称修饰是Python给类内部代码开的“绿色通道”,只有在类内部写的双下划线名称,才会被自动转换,类外部就没这个待遇啦。
内容的提问来源于stack exchange,提问作者Chillar Anand




