← Назад к вопросам

Как называется механизм, который скрывает приватное?

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: демократичность и доверие разработчикам.

Как называется механизм, который скрывает приватное? | PrepBro