Question

Possible Duplicate:
What is the benefit of private name mangling in Python?

While I was playing with python, I found that if class or instance variable-name starts with 2 underscores, they will be renamed so as to be preceded by '_'.

eg

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


test_instance = Test()

then both the variables will be renamed to

test_instance._Test__attribute and test_instance._Test__instance_attribute

Why is there such a behaviour/feature? Is there any need of that, or any special use intended of that?

I can think of a use case that when different classes have some attribute with a generic name, eg. value, id, member in common, but for some function/method we are expecting/assuming only one of these classes. In this case there is a chance that type checking is not being done and when another class instance is passed to it(maybe by mistake) may result in errors and/or undesired behaviour.

But apart from this use case I don't see any benefit of this special behaviour. The behaviour looks like a feature, pretty fundamental one, and I feel like I am missing something here. If it's a feature what is the use of it? Any typical use case?

Was it helpful?

Solution

Use of prefixing double underscore is called name mangling: (from the Python docs):

Any identifier of the form __spam (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__spam, where classname is the current class name with leading underscore(s) stripped. This mangling is done without regard to the syntactic position of the identifier, so it can be used to define class-private instance and class variables, methods, variables stored in globals, and even variables stored in instances. private to this class on instances of other classes.

Note that single underscore prefix is used to indicate that the variable / function / class should be private (although that is not strictly enforced)

OTHER TIPS

This feature is to help avoid name clashes with attributes when subclassing.

Consider the following:

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)

Now if you create an instance:

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

This essentially can be used to separate some of the behavior of the parent class (MyClass) from the behavior of the child class (MyClass2)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top