具有前导双下划线的实例/类属性的意义和用法(特殊行为)

时间:2012-12-14 14:18:40

标签: python attributes naming instance-variables class-variables

  

可能重复:
  What is the benefit of private name mangling in Python?

当我在玩python时,我发现如果classinstance变量名以2个下划线开头,它们将被重命名,以便在前面加上'_'。

例如

class Test(object):
    __attribute = "dunderscored"
    def __init__(self, value=0):
        self.__instance_attribute = value


test_instance = Test()

然后两个变量都将重命名为

test_instance._Test__attributetest_instance._Test__instance_attribute

为什么会出现这样的行为/特征?是否有任何需要,或者是否有任何特殊用途?

我可以想到一个用例,当不同的类具有一些通用名称的属性时,例如。 value,id,member of common,但是对于某些函数/方法,我们期望/假设只有这些类中的一个。在这种情况下,有可能没有进行类型检查,并且当另一个类实例传递给它时(可能是错误的)可能导致错误和/或不期望的行为。

但除了这个用例之外,我没有看到这种特殊行为的任何好处。这种行为看起来像一个功能,非常基本的,我觉得我在这里遗漏了一些东西。如果它是一个功能有什么用呢?任何典型的用例?

2 个答案:

答案 0 :(得分:3)

使用前缀双下划线称为名称修改:(来自Python docs):

  

__spam形式的任何标识符(至少两个前导下划线,最多一个尾随下划线)在文本上替换为_classname__spam,其中classname是当前类名,前导下划线被剥离。这种修改是在不考虑标识符的句法位置的情况下完成的,因此它可以用于定义类私有实例和类变量,方法,存储在全局变量中的变量,甚至存储在实例中的变量。对其他类的实例私有。

请注意,单个下划线前缀用于表示变量/ function / class应该是私有的(尽管严格强制执行)

答案 1 :(得分:1)

此功能有助于避免在子类化时使用属性进行名称冲突。

请考虑以下事项:

class MyClass1(object):
    def __init__(self):
         self.__attribute = 3

    def doSomething(self):
         print(self.__attribute)

class MyClass2(MyClass1):
    def __init__(self):
         MyClass1.__init__(self)
         self.__attribute = 4

    def doSomething2(self):
         print(self.__attribute)

现在,如果您创建一个实例:

x = MyClass2()
x.doSomething() #prints 3
x.doSomething2() #prints 4

这实际上可以用来将父类(MyClass)的某些行为与子类的行为(MyClass2)分开