What is the meaning of single and double underscore before an object name?

In Python, a single underscore "_" before an object name indicates that the object is meant to be private, meaning that it should not be directly accessed or modified outside of the class that it is defined in. This is simply a naming convention and does not actually enforce any kind of privacy.

A double underscore "__" before an object name is a way of "mangling" the name, which is a technique used to avoid name clashes between class attributes. When a name with double underscores is used, the name is changed in a way that makes it harder to accidentally overwrite it.

Watch a course Python - The Practical Guide

For example, if a class has an attribute with the name "__private", it might be internally stored as "_classname__private", where "classname" is the name of the class. This makes it less likely that another class will have an attribute with the same name, and therefore reduces the risk of name clashes. However, the double underscore notation does not provide any real protection against deliberately overwriting the attribute.

Here's an example of how the double underscore notation can be used to avoid name clashes between class attributes:

class MyClass:
    def __init__(self):
        self.__private = "private attribute"
        self.public = "public attribute"

obj = MyClass()

print(obj.public)      # Output: "public attribute"
print(obj.__private)  # AttributeError: 'MyClass' object has no attribute '__private'

In this example, the __private attribute is meant to be private and is not directly accessible from outside the MyClass class. However, the public attribute can be accessed and modified normally.

Note that the attribute name is actually stored as _MyClass__private internally, so it is possible to access it by using the name mangling technique. For example:

print(obj._MyClass__private)  # Output: "private attribute"

However, it is generally not recommended to access or modify private attributes using this technique, as it defeats the purpose of using the double underscore notation in the first place.