You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动