在Python中,对象名称前的单前导下划线和双前导下划线代表什么?
当前回答
为了用简单的语言来描述它,让我们将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
其他回答
_var:python中带前导单下划线的变量是经典变量,旨在通知使用代码的其他人该变量应保留供内部使用。它们与经典变量有一点不同:在对定义它们的对象/模块进行通配符导入时,不会导入它们(定义__all__变量时除外)。如:#foo.pyvar=“var”_var=“_var”#巴.py从foo导入*print(dir())#已定义对象的列表,包含“var”但不包含“_var”打印(var)#varprint(_var)#name错误:未定义名称“_var”_:单下划线是前导单下划线变量的特殊情况。按照惯例,它被用作垃圾变量,以存储一个不打算稍后访问的值。它也不会通过通配符导入来导入。这个for循环打印“我不能在课堂上讲话”10次,并且永远不需要访问_变量。对于范围(10)内的_:打印(“我不能在课堂上讲话”)var_:单尾随下划线变量。它们是传统的变量,用于避免与Python关键字冲突。如:class_=“MyClassName”__var:双前导下划线变量(至少两个前导下划线,最多一个尾随下划线)。当用作类属性(变量和方法)时,这些变量会受到名称篡改:在类之外,python会将属性重命名为_<class_name>__<attribute_name>。例子:类MyClass:__an_attribute=“属性值”my_class=我的类()print(my_class.MyClass__an_attribute)#“属性值”print(my_class.__an_attribute)#AttributeError:“MyClass”对象没有属性“__an_aattribute”当用作类外部的变量时,它们的行为类似于单前导下划线变量。__var__:双前导和尾随下划线变量(至少两个前导和尾随底线)。也称为dunders。python使用此命名约定在内部定义变量。避免使用此约定来防止python更新可能产生的名称冲突。Dunder变量的行为类似于单前导下划线变量:它们在类中使用时不受名称篡改的影响,但不会在通配符导入中导入。
根据Python中下划线的含义
单前导下划线(_var):表示名称仅供内部使用的命名约定。通常不由Python解释器强制执行(通配符导入除外),仅作为程序员的提示。单尾下划线(var_):按惯例使用,以避免与Python关键字的命名冲突。双前导下划线(__var):在类上下文中使用时触发名称更改。由Python解释器强制执行。双前导和尾随下划线(__var__):表示Python语言定义的特殊方法。避免为自己的属性使用此命名方案。单下划线(_):有时用作临时或不重要变量的名称(“不在乎”)。另外:Python REPL中最后一个表达式的结果。
你的问题很好,不仅仅是关于方法。模块中的函数和对象通常也以一个下划线作为前缀,也可以以两个下划线作为后缀。
例如,__double_underscore名称在模块中不会被篡改。如果从一个模块(从模块导入*)导入所有名称,则不会导入以一个(或多个)下划线开头的名称,也不会导入帮助(模块)中显示的名称。
有时,您会看到一个带有前导下划线的元组,如
def foo(bar):
return _('my_' + bar)
在本例中,发生的情况是,_()是本地化函数的别名,该函数根据语言环境对文本进行操作以将其转换为适当的语言等。例如,Sphinx这样做,您可以在导入中找到
from sphinx.locale import l_, _
在sphinx.locale中,_()被指定为某个本地化函数的别名。
单个下划线
在类中,带前导下划线的名称向其他程序员表示该属性或方法将在该类中使用。然而,隐私权并未以任何方式强制执行。对模块中的函数使用前导下划线表示不应从其他地方导入。
从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!'}
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换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中获得所有直接子目录