Python中单下划线与双下划线的命名约定及Name Mangling机制解析

小满
小满
发布时间:2026-10-13 | 3人浏览过
原创

本文详解Python中单下划线(_)与双下划线(__)的命名区别。单下划线为编程约定,提示属性或方法为内部使用,不影响实际访问权限;双下划线触发Name Mangling机制,通过自动重命名防止子类覆盖,实现类似私有化的效果。文章通过代码示例解析其工作原理及访问限制。

引言

在研读Python开源项目源码时,开发者常会遇到以单下划线或双下划线开头的方法与属性。这些命名方式究竟有何具体作用,彼此之间又存在哪些关键差异?本文将对此进行系统梳理(注:以下示例代码均基于Python3环境测试通过)。

单下划线(_)的语义与约定

单下划线(_)的语义与约定

需要明确的是,Python语言层面并不存在严格的“私有”属性或方法概念,即没有强制性的访问控制机制。

然而,为了提升代码的可维护性与模块化管理,开发者通常需要在代码中区分“私有”与“共有”接口,以便更好地控制调用范围。那么在Python中应如何实现这一目标?

Python社区遵循一项广泛接受的约定:在属性或方法名前添加单下划线_,即表示该成员为“私有”。这旨在提示其他开发者,该成员不应在模块外部直接调用,且在使用`from ModuleA import *`语句导入时,该成员会被自动排除。尽管强行调用不会引发语法错误,但这违背了Python的编码规范。

以下代码演示了带有单下划线的方法定义,以及其在类外部被访问时的行为表现。


class TestA:
  def _method(self):
    print('I am a private function.')
  def method(self):
    return self._method()
ca = TestA()
ca.method()

运行输出结果如下:

I am a private function.

在类TestA中,我们定义了_method方法。按照约定,该方法不应在类外部直接调用。为了提供安全的访问接口,我们定义了method方法,由它内部调用_method方法。

但必须牢记,添加单下划线并不禁止外部调用,该方法仍可在类外部被访问:


ca._method()

运行输出结果如下:

I am a private function.

双下划线(__)的语义与Name Mangling机制

双下划线(__)的语义与Name Mangling机制

Python中的双下划线与一项名为Name Mangling(名称修饰或名称重整)的技术密切相关。在现代编程语言中,该技术常用于解决因唯一命名需求引发的冲突问题,例如命名冲突或方法重载等场景。

在Python中,以双下划线开头的方法或属性,旨在防止子类覆盖(Override)该成员。其实现原理是:在类实例化过程中,Python会自动对双下划线开头的成员名称进行转换,即在原名称前添加“_类名”前缀。


class TestA:
  def __method(self):
    print('This is a method from class TestA')
  def method(self):
    return self.__method()
class TestB(TestA):
  def __method(self):
    print('This is a method from calss TestB')
ca = TestA()
cb = TestB()
ca.method()
cb.method()

运行输出结果如下:

This is a method from class TestA This is a method from class TestB

在类TestA中,__method方法由于Name Mangling机制的作用,实际上被自动重命名为_TestA__method。因此,在TestA中,method方法返回的是_TestA__method的调用结果。当TestB继承TestA并重写__method时,它并未重写method方法。因此,调用TestB实例的method方法时,实际执行的仍是父类的_TestA__method逻辑。

需要注意的是,在类TestA内部,并不存在名为__method的成员,实际存在的是_TestA__method。开发者仍可在外部直接调用转换后的名称,这再次证明了Python中不存在绝对的私有化。

若尝试直接调用__method(),将会失败,必须使用转换后的名称进行调用。


ca.__method()

运行输出结果如下:

Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'TestA' object has no attribute '__method'

转换后的实际方法名为:_TestA__method


ca._TestA__method()

运行输出结果如下:

This is a method from class TestA

若在TestB中重写method方法:


class TestB(TestA):
  def __method(self):
    print('This is a method from calss TestB')
  def method(self):
    return self.__method()
cb = B()
cb.method()

运行输出结果如下:

This is a method from calss TestB

此时,TestB中的method方法将调用_TestB__method。

1、_xxx(单下划线开头)不能通过`from module import *`导入。以单下划线开头的变量被视为protected(受保护)类型,即仅允许该类本身及其子类访问。

2、__xxx(双下划线开头)表示私有类型的变量。理论上仅允许该类本身访问,子类也不可直接访问或覆盖。

3、__xxx__(双下划线前后均有)定义的是特殊方法(Magic Methods),例如__init__、__str__等。

总结

总结

Python中并没有真正的私有化机制,但存在一系列与命名相关的约定,用于辅助开发者处理需要限制访问权限的场景。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表