Ответ
Инкапсуляция в Python — это в первую очередь соглашение, а не строгий механизм контроля доступа, как в Java или C++. Доступ к атрибутам технически не ограничивается, но используются специальные префиксы для именования.
-
_
(один префикс): Сигнализирует, что атрибут или метод является защищенным (protected). Это договоренность между разработчиками о том, что его не следует использовать вне класса или его наследников. Технически доступ остается открытым. -
__
(два префикса): Включает механизм искажения имен (name mangling). Интерпретатор автоматически переименовывает атрибут, добавляя в начало имя класса. Это делается для предотвращения случайных конфликтов имен в дочерних классах, а не для строгого сокрытия.
Пример:
class MyClass:
def __init__(self):
self.public_var = "Я публичный"
self._protected_var = "Я защищенный"
self.__private_var = "Я приватный"
obj = MyClass()
# Прямой доступ
print(obj.public_var) # >> Я публичный
print(obj._protected_var) # >> Я защищенный (но IDE предупредит)
# Попытка прямого доступа к "приватному" атрибуту вызовет ошибку
try:
print(obj.__private_var)
except AttributeError as e:
print(e) # >> 'MyClass' object has no attribute '__private_var'
# Доступ через искаженное имя все еще возможен
print(obj._MyClass__private_var) # >> Я приватный
Таким образом, инкапсуляция в Python полагается на дисциплину программиста, а не на принудительные ограничения языка.