前后下划线的python属性有啥区别[重复]
Posted
技术标签:
【中文标题】前后下划线的python属性有啥区别[重复]【英文标题】:What is the difference in python attributes with underscore in front and back [duplicate]前后下划线的python属性有什么区别[重复] 【发布时间】:2013-01-18 06:03:12 【问题描述】:可能重复:The meaning of a single- and a double-underscore before an object name in Python
我想知道Python中这些有什么区别?
self._var1
self._var1_
self.__var1
self.__var1__
【问题讨论】:
可能重复:***.com/questions/1301346/… 和 ***.com/questions/935378/… 【参考方案1】:作为起点,您可能会发现 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
字段相同的地方使用前导下划线,但请注意该语言实际上并没有强制访问 - 相反,您相信您的班级的用户不会做任何愚蠢的事情,让他们选择访问(或修改)您班级的私有字段,如果他们真的非常确定他们知道自己在做什么并且有意义的话。
单首尾下划线
self._var1_
不是我见过的东西。我认为这种命名风格在 Python 世界中没有任何传统意义。
双前导下划线
这个实际上有句法意义。在您的类范围内引用self.__var1
会调用name mangling。在您的班级之外,该变量将出现在self._YourClassName__var1
而不是self.__var1
。不是每个人都使用它——我们在我工作的地方根本不使用它——对于简单的类来说,使用单个前导下划线感觉有点荒谬和令人恼火。
但是,它的存在是有理由的;如果您使用大量继承,如果您只使用单个前导下划线,那么您将无法向阅读您的代码的人指示“私有”和“受保护”变量之间的区别 - 甚至不意味着被子类访问,子类可以访问但外部世界不能访问的。因此,在这种情况下,使用单个尾随下划线表示“受保护”,使用双下划线表示“私有”可能是一个有用的约定(名称修饰将允许子类在其子类中使用具有相同名称的变量而不会导致碰撞)。
双前导和尾随下划线
self.__var1__
是你永远不应该创建的东西,因为我已经写了它,因为双前导和尾随下划线命名样式仅用于具有 Python 定义的特殊含义的名称,例如 @987654344 @ 或 __eq__
类的方法。你可以随意覆盖这些来改变你的类的行为(事实上,几乎所有的类都会有一个程序员定义的__init__
),但你不应该用这种风格自己命名,比如self.__var1__
。
【讨论】:
在docs中也有详细说明。 “单前导和尾随下划线”:这在某些项目中用作用户可修改的特殊方法等效项的约定。例如,我们在Sage 中使用它。我在其他地方也看到过,虽然我想不出一个例子。 双前导下划线的最后三行应反之:单下划线=私有,双下划线=受保护 @amirteymuri 不,这是完全错误的。名称修改使得无法将双下划线方法用作受保护的方法。以上是关于前后下划线的python属性有啥区别[重复]的主要内容,如果未能解决你的问题,请参考以下文章
请问vc中为啥有的函数前缀为下划线,有的函数无下划线?两者有啥区别?