← Назад к вопросам
Как называется механизм, который скрывает приватное?
1.2 Junior🔥 131 комментариев
#Python Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Name Mangling — механизм скрытия приватных атрибутов
В Python механизм называется Name Mangling (переименование имён). Это способ защитить приватные атрибуты класса от случайного доступа.
1. Двойное подчёркивание — инициирует Name Mangling
class MyClass:
def __init__(self):
self.__private = "секрет" # Приватный атрибут
self._protected = "защищённый" # Защищённый (условность)
self.public = "публичный" # Публичный
obj = MyClass()
# Прямой доступ не работает
try:
print(obj.__private) # AttributeError
except AttributeError as e:
print(f"Ошибка: {e}")
# Но Python переименовал атрибут
print(obj._MyClass__private) # "секрет" — NAME MANGLING!
print(dir(obj)) # Можно увидеть '_MyClass__private'
2. Как работает Name Mangling
Питон автоматически преобразует __attribute в _ClassName__attribute:
class Bank:
def __init__(self, balance):
self.__balance = balance # Будет переименовано
def get_balance(self):
return self.__balance
def deposit(self, amount):
if amount > 0:
self.__balance += amount
bank = Bank(1000)
# Правильный способ
print(bank.get_balance()) # 1000
bank.deposit(500)
print(bank.get_balance()) # 1500
# "Неправильный" (но технически возможный)
print(bank._Bank__balance) # 1500 — можно получить доступ!
bank._Bank__balance = -9999 # Но это плохая практика
3. Двойное подчёркивание в методах
class Car:
def __init__(self):
self.__engine_status = "off"
def __start_engine(self): # Приватный метод
self.__engine_status = "running"
print("Двигатель запущен")
def __stop_engine(self): # Приватный метод
self.__engine_status = "off"
print("Двигатель остановлен")
def drive(self): # Публичный метод
self.__start_engine()
print("Едим!")
self.__stop_engine()
car = Car()
car.drive() # Работает
# car.__start_engine() # AttributeError
car._Car__start_engine() # Технически возможно, но не делайте так!
4. Одиночное подчёркивание — условность
Одиночное подчёркивание — просто договорённость, не механизм:
class Configuration:
def __init__(self):
self._internal_config = {} # Условно защищённый
self.public_config = {} # Публичный
def _validate_config(self): # Условно приватный метод
# Валидировать конфиг
pass
config = Configuration()
# Все эти доступы будут работать
print(config._internal_config)
config._validate_config()
# Это просто договорённость: "пожалуйста, не используй это"
5. Нет истинной приватности в Python
Python придерживается философии: "Мы все взрослые люди"
class Secret:
def __init__(self):
self.__secret = "Это не так секретно"
secret = Secret()
# Можно получить доступ несколькими способами
print(secret._Secret__secret) # Прямо через Name Mangling
print(secret.__dict__) # Через словарь атрибутов
# Нет истинной защиты, только договорённости
6. Практический пример — инкапсуляция
class Temperature:
def __init__(self, celsius=0):
self.__celsius = celsius
@property
def celsius(self):
return self.__celsius
@celsius.setter
def celsius(self, value):
if value < -273.15:
raise ValueError("Невозможная температура")
self.__celsius = value
@property
def fahrenheit(self):
return self.__celsius * 9/5 + 32
temp = Temperature(25)
print(temp.celsius) # 25
print(temp.fahrenheit) # 77.0
temp.celsius = -274 # ValueError: Невозможная температура
7. Когда использовать Name Mangling
# ✓ Используй для защиты внутреннего состояния
class DatabaseConnection:
def __init__(self):
self.__connection = None # Скрыть от прямого доступа
def connect(self):
self.__connection = open_db_connection()
def execute(self, query):
if self.__connection is None:
raise RuntimeError("Нет подключения")
return self.__connection.execute(query)
# ✗ Не переусложняй для простых данных
class Point: # Здесь достаточно одиночного подчёркивания
def __init__(self, x, y):
self._x = x # Не обязательно скрывать
self._y = y
8. Работа с наследованием
class Parent:
def __init__(self):
self.__private = "родитель"
self._protected = "защищено"
class Child(Parent):
def __init__(self):
super().__init__()
self.__private = "ребёнок" # Отдельный атрибут!
def show(self):
# Доступен _protected
print(self._protected)
# Но __private ребёнка — свой, родителя не видно
print(self.__private) # "ребёнок"
# Родительский приватный недоступен
# print(self.__private) # AttributeError
child = Child()
child.show()
Ключевые моменты
- Name Mangling — автоматическое переименование
__attributeв_ClassName__attribute - Двойное подчёркивание — инициирует Name Mangling
- Одиночное подчёркивание — просто условность, не механизм
- Нет истинной приватности — Python доверяет программистам
- Цель — защитить от случайного (не намеренного) доступа
- Наследование — Name Mangling препятствует конфликтам имён в иерархии классов
Name Mangling — это компромисс между безопасностью и философией Python: демократичность и доверие разработчикам.