17

Python provides private name mangling for class methods and attributes.

Are there any concrete cases where this feature is required, or is it just a carry over from Java and C++?

Please describe a use case where Python name mangling should be used, if any?

Also, I'm not interested in the case where the author is merely trying to prevent accidental external attribute access. I believe this use case is not aligned with the Python programming model.

martineau
  • 119,623
  • 25
  • 170
  • 301
cmcginty
  • 113,384
  • 42
  • 163
  • 163

4 Answers4

30

It's partly to prevent accidental internal attribute access. Here's an example:

In your code, which is a library:

class YourClass:
    def __init__(self):
        self.__thing = 1           # Your private member, not part of your API

In my code, in which I'm inheriting from your library class:

class MyClass(YourClass):
    def __init__(self):
        # ...
        self.__thing = "My thing"  # My private member; the name is a coincidence

Without private name mangling, my accidental reuse of your name would break your library.

RichieHindle
  • 272,464
  • 47
  • 358
  • 399
  • 1
    IMO, YourClass should define _thing, instead of __thing. This would allow MyClass to access it. Second, I see the benefit of using '__thing' in MyClass, if there is concern that the YourClass implementation will change. The only problem, is that if someone wants to subclass MyClass, then you've made it more difficult for them to access 'MyClass.__thing'. It feels like you are sacrificing future reuse, to protect against an "imaginary" problem. No? – cmcginty Jul 21 '09 at 23:46
  • 5
    @Casey: You're right that there are member variables that you want to be visible to subclasses, and those you name with a single underscore. You'd make them `protected` in C++. But there are also members that you *don't* want to be visible to subclasses, because they're part of the private implementation of your class (and as you say, they're subject to the implementation changing). It's these that name mangling is for. This isn't an imaginary problem; I've actually done exactly the thing I'm talking about, with a library that used a single underscore rather than a double for a private member. – RichieHindle Jul 22 '09 at 05:48
  • @RichieHindle: Exactly. Except that this is an EXTERNAL access. ;) The subclass is seen as external here. – Lennart Regebro Jul 22 '09 at 11:14
  • 1
    Aren't the "private" implementation details arbitrary? If I was creating a base class to distribute to the world, and I can't conceive of all the possible usage scenarios, then how can I reliable choose which attributes are "protected" and which are "private". In the end, there will always be a reason that someone might need to access a variable to extend/enhance the class. Using mangled attribute names, then is no benefit, and will simply force the next person to un-mangle them. – cmcginty Jul 22 '09 at 21:39
  • 7
    I think we'll have to agree to differ on that. IMHO, a well written library class has two APIs, one for direct users of that class, and one for classes that inherit from it. By convention, the former uses names with no underscores, and the latter can access single-underscore names. But the class still has the right to hide some of its implementation details - those that don't form part of either API - away from both types of user. Otherwise changes to the internal workings of the class become near-impossible, because you can't know anything about how your members are being used by subclasses. – RichieHindle Jul 22 '09 at 21:51
  • Please can you mention an example for - "my accidental reuse of your name would break your library". I am trying to understand this. – variable Dec 05 '19 at 04:30
  • Inheriting from the class and "accidentally" re-using the private name as a coincidence is about as likely as accidentally re-using the mangled name `_YourClass__thing`. I don't really see how this avoids that problem, just moves it a little to the right. If that was the real intention, why isn't the mangled name a random UUID4 or something? – wim Dec 05 '19 at 04:44
  • @wim since the format of a mangled name is part of the language spec, your example conflict can and should *always* be avoided. However, for unmangled attributes, a library author cannot prevent clashes with subclasses, because she has no access to the subclass'es code. – Joooeey Apr 19 '23 at 22:37
15

From PEP 8:

If your class is intended to be subclassed, and you have attributes that you do not want subclasses to use, consider naming them with double leading underscores and no trailing underscores. This invokes Python's name mangling algorithm, where the name of the class is mangled into the attribute name. This helps avoid attribute name collisions should subclasses inadvertently contain attributes with the same name.

(Emphasis added)

too much php
  • 88,666
  • 34
  • 128
  • 138
4

All previous answers are correct but here is another reason with an example. Name Mangling is needed in python because to avoid problems that could be caused by overriding attributes. In other words, in order to override, the Python interpreter has to be able to build distinct id for child method versus parent method and using __ (double underscore) enable python to do this. In below example, without __help this code would not work.

class Parent:
    def __init__(self):
       self.__help("will take child to school")
    def help(self, activities):
        print("parent",activities)

    __help = help   # private copy of original help() method

class Child(Parent):
    def help(self, activities, days):   # notice this has 3 arguments and overrides the Parent.help()
        self.activities = activities
        self.days = days
        print ("child will do",self.activities, self.days)


# the goal was to extend and override the Parent class to list the child activities too
print ("list parent & child responsibilities")
c = Child()
c.help("laundry","Saturdays")
grepit
  • 21,260
  • 6
  • 105
  • 81
  • 1
    That's interesting, but couldn't you just as well use `Parent.help()` in `Parent.__init__`, without defining the `__help`? – NirIzr Jun 03 '19 at 09:43
  • 1
    Yes, you could also do `Parent.help(self, "will take child to school")`. I think the point of this answer is to demonstrate that it actually allows a way for parent class to "opt out" of using the methods (or attributes) overridden in subclass. – wim Dec 05 '19 at 04:49
-1

The name mangling is there to prevent accidental external attribute access. Mostly, it's there to make sure that there are no name clashes.

Lennart Regebro
  • 167,292
  • 41
  • 224
  • 251