Python 对象名称前的单下划线和双下划线是什么意思?

Python 对象名称前的单下划线和双下划线是什么意思?,python,oop,naming-conventions,identifier,Python,Oop,Naming Conventions,Identifier,有人能解释一下Python中在对象名称前加一个和两个前导下划线的确切含义,以及两者之间的区别吗 此外,无论所讨论的对象是变量、函数、方法等,该含义是否保持不变?单下划线 在类中,带有前导下划线的名称只是向其他程序员指示属性或方法是私有的。然而,这个名字本身并没有什么特别之处 引述: _单前导下划线:弱“内部使用”指示器。例如,M import*中的不会导入名称以下划线开头的对象 双下划线(名称混乱) 发件人: 格式为\uuuu spam的任何标识符(至少两个前导下划线,最多一个尾随下划线)以文本

有人能解释一下Python中在对象名称前加一个和两个前导下划线的确切含义,以及两者之间的区别吗

此外,无论所讨论的对象是变量、函数、方法等,该含义是否保持不变?

单下划线 在类中,带有前导下划线的名称只是向其他程序员指示属性或方法是私有的。然而,这个名字本身并没有什么特别之处

引述:

_单前导下划线:弱“内部使用”指示器。例如,M import*中的
不会导入名称以下划线开头的对象

双下划线(名称混乱) 发件人:

格式为
\uuuu spam
的任何标识符(至少两个前导下划线,最多一个尾随下划线)以文本形式替换为
\u classname\uuuuu spam
,其中
classname
是带前导下划线的当前类名。这种篡改是在不考虑标识符的语法位置的情况下完成的,因此可以使用它来定义类私有实例和类变量、方法、全局变量中存储的变量,甚至实例中存储的变量。在其他类的实例上对此类专用

以及来自同一页面的警告:

名称混乱旨在为类提供一种定义“私有”实例变量和方法的简单方法,而不必担心派生类定义的实例变量,也不必担心类外的代码会弄乱实例变量。请注意,撕碎规则的设计主要是为了避免事故;一个坚定的灵魂仍然有可能访问或修改一个被认为是私有的变量

例子
>>类MyClass():
...     定义初始化(自):
...             self.\uu superprivate=“你好”
...             self._semiprivate=“,世界!”
...
>>>mc=MyClass()
>>>打印mc.\uuu superprivate
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
AttributeError:myClass实例没有属性“\uu superprivate”
>>>打印mc.\u半私有
世界!
>>>打印命令__
{“我的班级超级私人”:“你好”,“半私人”:“世界!”
单下划线 在类中,带有前导下划线的名称只是向其他程序员指示属性或方法是私有的。然而,这个名字本身并没有什么特别之处

引述:

_单前导下划线:弱“内部使用”指示器。例如,M import*
中的
不会导入名称以下划线开头的对象

双下划线(名称混乱) 发件人:

格式为
\uuuu spam
的任何标识符(至少两个前导下划线,最多一个尾随下划线)以文本形式替换为
\u classname\uuuuu spam
,其中
classname
是带前导下划线的当前类名。这种篡改是在不考虑标识符的语法位置的情况下完成的,因此可以使用它来定义类私有实例和类变量、方法、全局变量中存储的变量,甚至实例中存储的变量。在其他类的实例上对此类专用

以及来自同一页面的警告:

名称混乱旨在为类提供一种定义“私有”实例变量和方法的简单方法,而不必担心派生类定义的实例变量,也不必担心类外的代码会弄乱实例变量。请注意,撕碎规则的设计主要是为了避免事故;一个坚定的灵魂仍然有可能访问或修改一个被认为是私有的变量

例子
>>类MyClass():
...     定义初始化(自):
...             self.\uu superprivate=“你好”
...             self._semiprivate=“,世界!”
...
>>>mc=MyClass()
>>>打印mc.\uuu superprivate
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
AttributeError:myClass实例没有属性“\uu superprivate”
>>>打印mc.\u半私有
世界!
>>>打印命令__
{“我的班级超级私人”:“你好”,“半私人”:“世界!”

单前导下划线是一种惯例。如果名称是否以一个下划线开头,则从解释器的角度来看没有区别

双前导下划线和尾随下划线用于内置方法,如
\uuuuu init\uuuuu
\uuuuuu bool\uuuu


带尾随的双前导下划线也是一种惯例,但是,类方法将由解释器执行。对于变量或基本函数名,不存在任何差异。

单前导下划线是一种惯例。如果名称是否以一个下划线开头,则从解释器的角度来看没有区别

双前导下划线和尾随下划线用于内置方法,如
\uuuuu init\uuuuu
\uuuuuu bool\uuuu


带尾随的双前导下划线也是一种惯例,但是,类方法将由解释器执行。对于变量或基本函数名不存在任何差异。

\uuuufoo\uuuu
:这只是一种约定,Python系统使用的名称不会与用户名冲突

\u foo
:这只是一种约定,程序员可以通过这种方式指示变量是私有的(无论在Python中是什么意思)

\uuuufoo
:这具有真正的意义:解释器将此名称替换为
\u classname\uuuuufoo
,以确保该名称不会与另一个类中的类似名称重叠

在Python世界中,没有其他形式的下划线具有意义


在这些约定中,类、变量、全局等之间没有区别。

\uuuuufoo\uuuu
:这只是一种约定,是Python系统的一种方式
>>> 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!'}
def foo(bar):
    return _('my_' + bar)
from sphinx.locale import l_, _
class Test(object):
    def __init__(self):
        self.__a = 'a'
        self._b = 'b'

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

    def get_x(self):
        pass

    def set_x(self, val):
        pass

    rwvar = property(get_p, set_p)  

    ronly = property(get_p) 
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"
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'
class BaseForm(StrAndUnicode):

    def _get_errors(self):
        "Returns an ErrorDict for the data provided for the form"
        if self._errors is None:
            self.full_clean()
        return self._errors

    errors = property(_get_errors)
class A(object):
    def __test(self):
        print "I'm a test method in class A"

    def test(self):
        self.__test()

a = A()
a.test()
# a.__test() # This fails with an AttributeError
a._A__test() # Works! We can access the mangled name directly!
$ python test.py
I'm test method in class A
I'm test method in class A
class B(A):
    def __test(self):
        print "I'm test method in class B"

b = B()
b.test()
$ python test.py
I'm test method in class A
>>> name = "test string"
>>> name.__len__()
11
>>> len(name)
11

>>> number = 10
>>> number.__add__(40)
50
>>> number + 50
60
class FalseCalculator(object):

    def __init__(self, number):
        self.number = number

    def __add__(self, number):
        return self.number - number

    def __sub__(self, number):
        return self.number + number

number = FalseCalculator(20)
print number + 10      # 10
print number - 20      # 40
_
__
class Circle(object):

    def __init__(self, radius):
        self.radius = radius

    def area(self):
        p = self.__perimeter()
        r = p / math.pi / 2.0
        return math.pi * r ** 2.0

    def perimeter(self):
        return 2.0 * math.pi * self.radius

    __perimeter = perimeter  # local reference


class Tire(Circle):

    def perimeter(self):
        return Circle.perimeter(self) * 1.25
class Tire(Circle):

    def perimeter(self):
        return Circle.perimeter(self) * 1.25

    _perimeter = perimeter
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)
# Private methods of MyClass
def _MyClass__do_something(obj:'MyClass'):
    print('_MyClass__do_something() called. type(obj) = {}'.format(type(obj)))

class MyClass():
    def __init__(self):
        __do_something(self)

mc = MyClass()
_MyClass__do_something() called. type(obj) = <class '__main__.MyClass'>