一尘不染

对象名称前的单下划线和双下划线是什么意思?

python

有人可以解释一下 Python 中对象名称前有单下划线和双下划线的确切含义,以及两者之间的区别吗?

此外,无论所讨论的对象是变量、函数、方法等,其含义是否保持不变?


阅读 192

收藏
2022-02-22

共1个答案

一尘不染

单下划线

在一个类中,带有前导下划线的名称只是为了向其他程序员表明该属性或方法是私有的。但是,名称本身并没有什么特别之处。

引用PEP-8

_single_leading_underscore:弱“内部使用”指标。例如from M import *,不导入名称以下划线开头的对象。

双下划线(名称修饰)

来自Python 文档

形式的任何标识符__spam(至少两个前导下划线,最多一个尾随下划线)在文本上替换为_classname__spam,其中classname是当前类名,前导下划线被剥离。这种修饰是在不考虑标识符的语法位置的情况下完成的,因此它可以用于定义类私有实例和类变量、方法、存储在全局变量中的变量,甚至是存储在实例中的变量。在其他类的实例上对此类是私有的。

来自同一页面的警告:

名称修改旨在为类提供一种简单的方法来定义“私有”实例变量和方法,而不必担心派生类定义的实例变量,或通过类外的代码混淆实例变量。请注意,修改规则主要是为了避免事故。一个坚定的灵魂仍然有可能访问或修改一个被认为是私有的变量。

例子

>>> class MyClass():
...     def __init__(self):
...             self.__superprivate = "Hello"
...             self._semiprivate = ", world!"
...
>>> mc = MyClass()
>>> print mc.__superprivate
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: myClass instance has no attribute '__superprivate'
>>> print mc._semiprivate
, world!
>>> print mc.__dict__
{'_MyClass__superprivate': 'Hello', '_semiprivate': ', world!'}
2022-02-22