Ответ
В Python префиксы с подчеркиванием используются для управления видимостью и поведением имен атрибутов и методов класса, следуя соглашениям и задействуя встроенные механизмы языка.
1. Одиночное подчеркивание (_
)
Это соглашение (convention), которое сигнализирует другим разработчикам, что атрибут или метод предназначен для внутреннего использования внутри класса или модуля. Интерпретатор Python никак не ограничивает доступ к таким именам, но они не импортируются при использовании from module import *
.
Назначение:
- Подсказать, что это внутренняя деталь реализации, которую не следует использовать извне.
- Избежать засорения пространства имен при импорте со звездочкой.
Пример:
class MyWidget:
def __init__(self):
self.public_data = 10
self._internal_data = 20 # Считается внутренним
def _helper_method(self):
# Внутренний вспомогательный метод
return "Helper result"
w = MyWidget()
print(w.public_data) # OK
print(w._internal_data) # Технически возможно, но не рекомендуется
2. Двойное подчеркивание (__
)
Это не просто соглашение, а запуск механизма искажения имен (name mangling). Python автоматически изменяет имя атрибута, добавляя к нему префикс _ИмяКласса
.
Назначение:
- Избежать случайного переопределения (конфликта имен) в дочерних классах.
Пример:
class Parent:
def __init__(self):
self.__private_var = "I am from Parent"
def get_var(self):
return self.__private_var
class Child(Parent):
def __init__(self):
super().__init__()
self.__private_var = "I am from Child"
obj = Child()
print(obj.get_var()) # Выведет: "I am from Parent"
# Прямой доступ невозможен
# print(obj.__private_var) # Вызовет AttributeError
# Доступ через искаженное имя все еще возможен
print(obj._Parent__private_var) # Выведет: "I am from Parent"
print(obj._Child__private_var) # Выведет: "I am from Child"
Ключевое различие: _
— это 'подсказка' для программиста, а __
— механизм, предотвращающий случайное переопределение в дочерних классах.