在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'

这对一些人来说可能很明显,但在一个复杂得多的环境中,这让我措手不及

其他回答

有时,您会看到一个带有前导下划线的元组,如

def foo(bar):
    return _('my_' + bar)

在本例中,发生的情况是,_()是本地化函数的别名,该函数根据语言环境对文本进行操作以将其转换为适当的语言等。例如,Sphinx这样做,您可以在导入中找到

from sphinx.locale import l_, _

在sphinx.locale中,_()被指定为某个本地化函数的别名。

.variable是半私有的,仅用于约定

.__variable通常被错误地认为是超级私有的,而它的实际含义只是为了命名mangle以防止意外访问[1]

.__variable__通常为内置方法或变量保留

您仍然可以访问__如果您非常想的话,可以对变量进行损坏。双下划线只是将变量命名为mangles或重命名为instance_类名__已损坏

例子:

class Test(object):
    def __init__(self):
        self.__a = 'a'
        self._b = 'b'

>>> t = Test()
>>> t._b
'b'

t.b是可访问的,因为它仅按惯例隐藏

>>> t.__a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Test' object has no attribute '__a'

找不到t.__a,因为它由于名称损坏而不再存在

>>> t._Test__a
'a'

通过访问实例_className__variable而不仅仅是双下划线名称,您可以访问隐藏值

很好的答案,而且都是正确的。我提供了简单的例子以及简单的定义/含义。

含义:

某些变量--► 这是公开的,任何人都可以看到。

_某些变量--► 这是公开的,任何人都可以看到,但这是一个惯例,表明私人。。。警告Python不执行强制。

__某些变量--► Python将变量名替换为_classname__some_varable(AKA name mangling),并降低/隐藏其可见性,更像是私有变量。

老实说,根据Python文档

无法访问的“Private”实例变量Python中不存在对象“

示例:

class A():
    here="abc"
    _here="_abc"
    __here="__abc"


aObject=A()
print(aObject.here) 
print(aObject._here)
# now if we try to print __here then it will fail because it's not public variable 
#print(aObject.__here)

_foo:只是惯例。程序员指示变量是私有的(无论在Python中意味着什么)。__foo:这有真正的意义。解释器将此名称替换为_classname__foo,以确保该名称不会与其他类中的类似名称重叠。__foo__:只是惯例。Python系统使用不会与用户名冲突的名称的方法。

在Python世界中,没有其他形式的下划线有意义。此外,在这些约定中,类、变量、全局等之间没有区别。

_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变量的行为类似于单前导下划线变量:它们在类中使用时不受名称篡改的影响,但不会在通配符导入中导入。