Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Задачи

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про Python: private, attribute, encapsulation

Какая роль у методов, имён атрибутов и переменных, начинающихся с двух подчёркиваний?

Этот вопрос проверяет понимание механизма name mangling (имя-преобразование) в Python и различие между "обычными" двойными подчёркиваниями и "магическими" методами __init__, __str__ и т.п.

Короткий ответ

Имена, начинающиеся с двух подчёркиваний и не заканчивающиеся двумя подчёркиваниями (__name) в классах, подвергаются механизму name mangling: интерпретатор переписывает имя в _ClassName__name. Это помогает избежать конфликтов имён в иерархии наследования и служит более сильной формой инкапсуляции, чем одинарный _. Доступ к таким атрибутам возможен, но их труднее случайно переопределить или использовать. Отдельно есть "магические" методы с двойными подчёркиваниями по обе стороны (__init__, __len__), которые не мэнглятся и используются самим Python для реализации протоколов и операторов.

Длинный ответ

1. Два подчёркивания и name mangling

Определение:
__name в теле класса — это имя, к которому применяется name mangling: интерпретатор переписывает его в _ClassName__name для уменьшения вероятности конфликтов и прямого доступа.

Цель — усилить инкапсуляцию и защиту от случайного использования, особенно при наследовании.

1.1. Как работает name mangling

Когда вы объявляете атрибут класса __secret, Python внутри класса заменяет его имя:

  • В классе User: __password → _User__password

  • В классе Admin: __password → _Admin__password

Python

class User:
    def __init__(self, password: str):
        self.__password = password  # станет self._User__password

    def check_password(self, value: str) -> bool:
        return self.__password == value


u = User("1234")
# print(u.__password)  # AttributeError
print(u._User__password)  # технически работает, но так делать не стоит

Таким образом:

  • Имя нельзя случайно переопределить в наследнике с тем же __name.

  • Внешний код не увидит очевидного атрибута __password при обычном использовании.

1.2. Отличия одинарного и двойного подчёркивания

  • _name:

    • Только соглашение.

    • Легко доступен снаружи без всяких трюков.

    • Не изменяется интерпретатором.

  • __name:

    • Подвергается name mangling → _ClassName__name.

    • Используется для "почти приватных" атрибутов и избежания конфликтов.

    • Всё еще доступен, но требуется знать "переписанное" имя.

Реальная "защита" условная: опытный разработчик всегда сможет прочитать и изменить эти поля, но для случайного использования это серьёзный барьер.

1.3. "Магические" методы: __init__, __len__ и другие

Отдельная категория — имена с двумя подчёркиваниями с двух сторон, например:

  • __init__

  • __str__

  • __len__

  • __call__

  • __enter__, __exit__

Определение:
"Магические методы" (dunder methods) — это специальные методы, которые Python вызывает автоматически для реализации операторов, протоколов и поведения объектов.

Важно:

  • Они не подвергаются name mangling.

  • Они фиксированы и описаны в документации языка.

  • Нельзя произвольно придумывать свои __something__ и ожидать, что Python будет их как-то магически вызывать.

Python

class User:
    def __init__(self, name: str):
        self.name = name

    def __str__(self) -> str:
        return f"User({self.name})"

u = User("Alice")
print(u)  # автоматически вызовется u.__str__()

1.4. Когда использовать двойное подчёркивание

Имеет смысл использовать __name когда:

  1. Вы проектируете класс, который будет расширяться и наследоваться другими разработчиками.

  1. Вам нужно спрятать внутренний атрибут, чтобы его случайно не переопределили в наследнике.

  1. Вы хотите показать, что это критичная внутренняя деталь реализации и её не следует трогать.

Пример:

Python

class BankAccount:
    def __init__(self, initial: int):
        self.__balance = initial  # сильная инкапсуляция

    def deposit(self, amount: int) -> None:
        self.__balance += amount

    def get_balance(self) -> int:
        return self.__balance

В отличие от _balance, атрибут __balance труднее случайно переопределить в наследниках.

Краткий вывод

Двойное подчёркивание в начале имени запускает механизм name mangling и делает атрибут "почти приватным", защищая его от случайных конфликтов и использования. Магические методы с __name__ формируют стандартные протоколы языка. В обычной практике чаще достаточно одинарного _, а __name полезен в сложных и расширяемых классах.

  • Аватар

    Python Guru

    Sergey Filichkin

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.

Уровень

  • Рейтинг:

    4

  • Сложность:

    4

Навыки

  • Python

    Python

Ключевые слова

#private

#attribute

#encapsulation

Подпишись на Python Developer в телеграм

  • Аватар

    Python Guru

    Sergey Filichkin

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.