可能重复:
The meaning of a single- and a double-underscore before an object name in Python
我想知道Python中这些有什么区别?
self._var1
self._var1_
self.__var1
self.__var1__
答案 0 :(得分:65)
作为一个起点,您可能会从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
中命名属性向类的用户指示该属性只能由类的内部(或者可能是子类的内部)访问,并且他们不需要直接访问它,并且可能不应该修改它。您应该在Java或C#中使用private
或protected
字段的相同位置使用前导下划线,但要注意该语言实际上并不强制执行非访问 - 相反,您相信您的class的用户不要做任何愚蠢的事情,并让他们选择访问(或修改)你班级的私人领域,如果他们真的,真的确定他们知道他们在做什么,这是有道理的。
self._var1_
不是我见过的东西。我认为这种命名风格在Python世界中没有任何传统意义。
这个实际上具有句法意义。在您班级范围内提及self.__var1
,请调用name mangling。从您的课外,该变量将显示为self._YourClassName__var1
而不是self.__var1
。不是每个人都使用这个 - 我们根本不会工作 - 对于简单的课程来说,使用单个前导下划线感觉有点荒谬和恼人。
然而,有理由存在它;如果你使用大量的继承,如果你只使用单个前导下划线,那么你没有办法向某人读取你的代码中“私有”和“受保护”变量之间的区别 - 那些甚至都不是要由子类访问,以及子类可以访问但外部世界可能不访问的子类。因此,在这种情况下,使用单个尾部下划线表示“受保护”和双下划线表示“私有”可能是一个有用的约定(并且名称修改将允许子类在其子类中使用具有相同名称的变量而不会导致碰撞)。
self.__var1__
是你应该永远不会创建的东西,因为双字母和尾部下划线命名样式仅用于具有Python定义的特殊含义的名称,例如__init__
或__eq__
类方法。您可以自由地覆盖那些以改变您的类的行为(事实上,几乎所有类都将有一个程序员定义的__init__
),但您不应该像self.__var1__
那样以这种方式编写自己的名字。