Names starting with two Python underscores are used to take advantage of the mangled mechanism rather than private attributes

In order to make Python variables and methods private attributes, I see people and articles whose names start with ** 2 underscores **, but in "PEP8: Python Code Style Guide", private attributes We recommend starting with ** 1 underscore **.

Explanation in PEP8

https://pep8-ja.readthedocs.io/ja/latest/

--_single_leading_underscore: ** Indicates that it is "used only internally" **. For example, from M import * does not import objects whose names start with an underscore. --__double_leading_underscore: When naming an attribute of a class, it calls the ** name mangling mechanism ** (the name __boo in class Foobar becomes _FooBar__boo, see also below. please


In general, ** the two underscores at the beginning of a name should only be used to avoid conflicting attributes of a class designed to be subclassed ** ..

Mangling mechanism

If you start the name with ** 2 underscores **, the name mangling mechanism (Name Mangling) works and the name is unique to the class. Redefining the same name in a subclass will be treated as different and will not be affected by the redefinition (name conflict) in the subclass. Please note that due to the two underscores, ** unintended operation results may occur **. The sample code using the mangling mechanism is shown below.

Sample code

If you run the following program, you can see that names starting with two underscores are treated differently even if the same name is defined in the subclass, and are forced to the attribute of the class where the process is written.

class Base:

    def __init__(self):
        self.value = "Base.value"
        self._value = "Base._value"
        self.__value = "Base.__value"

    def method(self):
        print("Base.method")

    def _method(self):
        print("Base._method")

    def __method(self):
        print("Base.__method")

    def base(self):
        print('base():')
        print(self.value)
        print(self._value)
        print(self.__value)  #Use your own even if name conflicts with subclasses
        self.method()
        self._method()
        self.__method()  #Use your own even if name conflicts with subclasses


class Sub(Base):

    def __init__(self):
        super().__init__()
        self.value = "Sub.value"
        self._value = "Sub._value"
        self.__value = "Sub.__value"

    def method(self):
        print("Sub.method")

    def _method(self):
        print("Sub._method")

    def __method(self):
        print("Sub.__method")

    def sub(self):
        print('sub():')
        print(self.value)
        print(self._value)
        print(self.__value)  #Use your own even if name conflicts with subclasses
        self.method()
        self._method()
        self.__method()  #Use your own even if name conflicts with subclasses


class SubSub(Sub):

    def __init__(self):
        super().__init__()
        self.value = "SubSub.value"
        self._value = "SubSub._value"
        self.__value = "SubSub.__value"

    def method(self):
        print("SubSub.method")

    def _method(self):
        print("SubSub._method")

    def __method(self):
        print("SubSub.__method")

    def subsub(self):
        print('subsub():')
        print(self.value)
        print(self._value)
        print(self.__value)  #Use your own even if name conflicts with subclasses
        self.method()
        self._method()
        self.__method()  #Use your own even if name conflicts with subclasses


subsub = SubSub()
subsub.base()
print()
subsub.sub()
print()
subsub.subsub()

Execution result


base():
SubSub.value
SubSub._value
Base.__value
SubSub.method
SubSub._method
Base.__method

sub():
SubSub.value
SubSub._value
Sub.__value
SubSub.method
SubSub._method
Sub.__method

subsub():
SubSub.value
SubSub._value
SubSub.__value
SubSub.method
SubSub._method
SubSub.__method

Recommended Posts

Names starting with two Python underscores are used to take advantage of the mangled mechanism rather than private attributes
How to specify attributes with Mock of python
Unify the environment of the Python development team starting with Poetry
Try to automate the operation of network devices with Python
Play with the password mechanism of GitHub Webhook and Python
Get the source of the page to load infinitely with python.
Memo of the program to get the date in two digits with javascript, Ruby, Python, shell script