48

可能重复:
Python中对象名称前的单下划线和双下划线的含义

我想知道这些在 Python 中有什么区别?

self._var1
self._var1_
self.__var1
self.__var1__
4

1 回答 1

86

作为起点,您可能会发现PEP 8 - Style Guide For Python Code中的这句话很有帮助:

此外,还可以识别以下使用前导或尾随下划线的特殊形式(这些通常可以与任何大小写约定结合使用):

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

single_trailing_underscore_: 按照惯例使用以避免与 Python 关键字冲突,例如 Tkinter.Toplevel(master, class_='ClassName')

__double_leading_underscore: 当命名一个类属性时,调用名称修饰(在类 FooBar 中,__boo变为_FooBar__boo; 见下文)。

__double_leading_and_trailing_underscore__: 存在于用户控制的命名空间中的“神奇”对象或属性。例如__init____import____file__。永远不要发明这样的名字;仅按记录使用它们。

不过,您是在类属性的上下文中询问的,所以让我们看一下您的具体示例:

单前导下划线

在类中命名属性self._var1向类的用户表明该属性只能由类的内部(或者可能是子类的内部)访问,并且他们不需要直接访问它并且可能不应该修改它。private您应该在与在 Java 或 C# 中使用or字段相同的地方使用前导下划线protected,但请注意该语言实际上并没有强制执行非访问 - 相反,您相信您的班级的用户不会做任何愚蠢的事情,然后离开如果他们真的非常确定他们知道自己在做什么并且有意义,他们可以选择访问(或修改)您班级的私有字段。

单个前导和尾随下划线

self._var1_不是我见过的东西。我认为这种命名风格在 Python 世界中没有任何传统意义。

双前导下划线

这实际上具有句法意义。self.__var1在您的类范围内引用会调用name mangling。在您的班级之外,该变量将显示为 atself._YourClassName__var1而不是self.__var1. 不是每个人都使用这个——我们在我工作的地方根本不用——对于简单的类来说,使用单个前导下划线感觉有点荒谬和令人恼火。

但是,它的存在是有道理的;如果您使用大量继承,如果您只使用单个前导下划线,那么您无法向阅读您的代码的人指示“私有”和“受保护”变量之间的区别 - 甚至不是意味着被子类访问,以及子类可以访问但外部世界不能访问的那些。因此,在这种情况下,使用单个尾随下划线表示“受保护”,使用双下划线表示“私有”可能是一个有用的约定(名称修饰将允许子类在其子类中使用具有相同名称的变量而不会导致碰撞)。

双前导和尾随下划线

self.__var1__ is something you should never create as I've literally written it, because the double leading and trailing underscore naming style is meant to be used only for names that have a special meaning defined by Python, like the __init__ or __eq__ methods of classes. You're free to override those to change your class's behavior (indeed, almost all classes will have a programmer-defined __init__), but you shouldn't make up your own names in this style like self.__var1__.

于 2013-02-03T10:33:25.277 回答