在Python中,对象名称前的单前导下划线和双前导下划线代表什么?
当前回答
下面是一个简单的示例,说明双下划线财产如何影响继承的类。因此,使用以下设置:
class parent(object):
__default = "parent"
def __init__(self, name=None):
self.default = name or self.__default
@property
def default(self):
return self.__default
@default.setter
def default(self, value):
self.__default = value
class child(parent):
__default = "child"
如果然后在python REPL中创建子实例,您将看到以下内容
child_a = child()
child_a.default # 'parent'
child_a._child__default # 'child'
child_a._parent__default # 'parent'
child_b = child("orphan")
## this will show
child_b.default # 'orphan'
child_a._child__default # 'child'
child_a._parent__default # 'orphan'
这对一些人来说可能很明显,但在一个复杂得多的环境中,这让我措手不及
其他回答
单个下划线
在类中,带前导下划线的名称向其他程序员表示该属性或方法将在该类中使用。然而,隐私权并未以任何方式强制执行。对模块中的函数使用前导下划线表示不应从其他地方导入。
从PEP-8风格指南:
_single_leading_underscore:“内部使用”指标较弱。例如,from M import*不会导入名称以下划线开头的对象。
双下划线(名称Mangling)
从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!'}
单一前导下划线是一种惯例。如果名称是否以单个下划线开头,则从解释器的角度来看没有区别。
双前导和尾随下划线用于内置方法,如__init__、__bool__等。
双前导下划线不带尾随对应符也是一种惯例,但是,类方法将被解释器破坏。对于变量或基本函数名不存在差异。
根据Python中下划线的含义
单前导下划线(_var):表示名称仅供内部使用的命名约定。通常不由Python解释器强制执行(通配符导入除外),仅作为程序员的提示。单尾下划线(var_):按惯例使用,以避免与Python关键字的命名冲突。双前导下划线(__var):在类上下文中使用时触发名称更改。由Python解释器强制执行。双前导和尾随下划线(__var__):表示Python语言定义的特殊方法。避免为自己的属性使用此命名方案。单下划线(_):有时用作临时或不重要变量的名称(“不在乎”)。另外:Python REPL中最后一个表达式的结果。
有时,您会看到一个带有前导下划线的元组,如
def foo(bar):
return _('my_' + bar)
在本例中,发生的情况是,_()是本地化函数的别名,该函数根据语言环境对文本进行操作以将其转换为适当的语言等。例如,Sphinx这样做,您可以在导入中找到
from sphinx.locale import l_, _
在sphinx.locale中,_()被指定为某个本地化函数的别名。
为了用简单的语言来描述它,让我们将python变量的可访问性约定与Java中的访问修饰符进行比较:
(Python) = (Java)
_single_underscore_variable = Protected (Accessible to class and its subclasses)
__double_underscore_variable = Private (Accessible to class itself only)
no_underscore_variable = Public (Accessible anywhere)
参考:https://www.tutorialsteacher.com/python/public-private-protected-modifiers
推荐文章
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 使用try和。Python中的if
- 如何在Python中获得所有直接子目录
- 我如何告诉matplotlib我已经完成了一个情节?
- 如何在Python中记录源文件名称和行号