Ответ
Двойное подчеркивание (__
) в начале имени атрибута класса (например, __my_var
) активирует механизм искажения имен (name mangling).
Его основная цель — избежать случайного переопределения атрибутов в дочерних классах, а не создание по-настоящему приватных переменных.
Как это работает?
Интерпретатор Python автоматически изменяет имя такого атрибута, добавляя к нему префикс _ИмяКласса
. Таким образом, атрибут __value
в классе MyClass
станет _MyClass__value
.
Пример без наследования:
class MyClass:
def __init__(self):
self.__private_attr = 42
obj = MyClass()
# Прямой доступ вызовет ошибку
# print(obj.__private_attr) # AttributeError
# Доступ через искаженное имя работает
print(obj._MyClass__private_attr) # Вывод: 42
Пример с наследованием (демонстрация основной цели):
Этот механизм предотвращает коллизии, если дочерний класс определяет атрибут с таким же именем.
class Parent:
def __init__(self):
self.__value = "Parent Value" # Преобразуется в _Parent__value
def get_value(self):
return self.__value
class Child(Parent):
def __init__(self):
super().__init__()
self.__value = "Child Value" # Преобразуется в _Child__value
def get_child_value(self):
return self.__value
c = Child()
print(c.get_value()) # Вывод: Parent Value
print(c.get_child_value()) # Вывод: Child Value
print(c.__dict__) # {'_Parent__value': 'Parent Value', '_Child__value': 'Child Value'}
Как видно из примера, атрибуты __value
в родительском и дочернем классах не конфликтуют, так как были преобразованы в разные имена.