Ответ
В Python нет строгой инкапсуляции и настоящих private атрибутов, как в Java или C++. Вместо этого используется механизм искажения имён (name mangling), который служит сильным соглашением и помогает избежать случайных конфликтов имён в иерархии наследования.
Как это работает
Чтобы объявить атрибут "приватным", его имя должно начинаться с двух подчёркиваний __ (но не заканчиваться ими). Интерпретатор Python автоматически изменяет имя такого атрибута, добавляя к нему префикс _ИмяКласса.
- Атрибут
__private_attrв классеMyClassстанет_MyClass__private_attr.
Это делает атрибут недоступным по его исходному имени извне класса, предотвращая случайное переопределение.
Пример
class MyClass:
def __init__(self):
self.public_attr = "I'm public"
self._protected_attr = "I'm protected (by convention)"
self.__private_attr = "I'm private (mangled)"
def get_private_attr(self):
return self.__private_attr
obj = MyClass()
# Прямой доступ к публичному атрибуту
print(obj.public_attr) # -> I'm public
# Попытка доступа к приватному атрибуту вызовет ошибку
try:
print(obj.__private_attr)
except AttributeError as e:
print(e) # -> 'MyClass' object has no attribute '__private_attr'
# Доступ к "искаженному" имени все еще возможен (но не рекомендуется)
print(obj._MyClass__private_attr) # -> I'm private (mangled)
Соглашения об именовании
-
_single_leading_underscore(одно подчёркивание):- Назначение: Сигнал для других разработчиков, что атрибут или метод предназначен для внутреннего использования (аналог
protected). - Поведение: Никакого специального синтаксического поведения. Доступ не ограничивается.
- Назначение: Сигнал для других разработчиков, что атрибут или метод предназначен для внутреннего использования (аналог
-
__double_leading_underscore(два подчёркивания):- Назначение: Имитация приватности и предотвращение конфликтов имён при наследовании.
- Поведение: Включается механизм искажения имён (
name mangling).
Ответ 18+ 🔞
А, слушай, про эти ваши подчёркивания в питоне! Ну, типа, как у нас в стране — полной приватности, блядь, не бывает, но можно сделать вид, что она есть.
Вот смотри, в Java или C++ там прям строго: private — и хрен тебе, а не доступ. А в Python — это всё театр, ёпта, один сплошной договорняк. Но договорняк, блядь, удобный!
Как эта хуйня работает
Хочешь сделать атрибут как бы приватным? Начинай его имя с двух подчёркиваний __. Интерпретатор, хитрая жопа, увидит это и скажет: «Ага, щас мы его спрячем!». И переименует его, добавив в начало _ИмяКласса.
- Было
__secretв классеMyClass? Стало_MyClass__secret.
Извне по имени __secret его уже не найдёшь — ну, чтобы какой-нибудь распиздяй в дочернем классе случайно не перезаписал.
Смотри, как это выглядит в деле
class MyClass:
def __init__(self):
self.public_attr = "Я на виду, как говно в проруби"
self._protected_attr = "Я как бы для своих (но зайди, если очень надо)"
self.__private_attr = "А я типа приватный (имя мне поменяли)"
def get_private_attr(self):
return self.__private_attr
obj = MyClass()
# К публичному — всегда добро пожаловать
print(obj.public_attr) # -> Я на виду, как говно в проруби
# Попробуй напрямую к приватному — получишь по ебалу
try:
print(obj.__private_attr)
except AttributeError as e:
print(e) # -> 'MyClass' object has no attribute '__private_attr'. Ну я же говорил!
# Но если ты, блядь, настырный и знаешь секретное имя — то вот оно, родимое
print(obj._MyClass__private_attr) # -> А я типа приватный (имя мне поменяли)
А теперь про негласные правила, которые все блядь соблюдают
-
Одно подчёркивание
_variable:- Что значит: «Чувак, это внутренняя кухня. Трогать можно, но если сломаешь — сам дурак». Типа
protected. - По факту: Никакой магии, просто все видят подчёркивание и делают умное лицо.
- Что значит: «Чувак, это внутренняя кухня. Трогать можно, но если сломаешь — сам дурак». Типа
-
Два подчёркивания
__variable:- Что значит: «Я серьёзно, не лезь. И да, чтобы имена в наследниках не конфликтовали, нахуй».
- По факту: Включается тот самый «мангинг» (name mangling), когда имя подменяется. Не приватность, а так, защита от дурака. Очень, кстати, годная штука.
Короче, вся система держится на честном слове и паре символов. Красиво, блядь!