Какие атрибуты и методы считаются публичными и приватными в Python и как реализуется сокрытие данных?
Что проверяют
Понимаете ли вы, что приватности в Python нет на уровне языка, а есть соглашения и один механизм против конфликта имён. Следом обычно спрашивают, во что превращается __attr и как контролировать доступ через property.
Как отвечать
Начните с принципа: доступ регулируется договорённостью, а не интерпретатором. Дальше три уровня:
- без подчёркивания: публичный интерфейс класса, менять его можно только с оглядкой на обратную совместимость;
- одно подчёркивание
_name: внутреннее по соглашению, PEP 8 называет это слабым индикатором внутреннего использования. Доступ извне работает, но линтеры и IDE предупредят. На уровне модуля такие имена не импортируетfrom module import *, если их нет в__all__; - два подчёркивания
__name: включают name mangling. Внутри классаExampleимяself.__secretпревращается вself._Example__secret. Цель не спрятать данные, а защитить атрибут от случайного переопределения в подклассе. Имена с двумя подчёркиваниями с обеих сторон, вроде__init__, не искажаются, это специальные методы.
Сокрытие данных на практике делают через @property: геттер отдаёт значение, сеттер валидирует, и публичный атрибут можно превратить в свойство, не меняя код вызывающих. Дополнительно помогают __slots__, который не даёт заводить на экземпляре новые атрибуты, и @dataclass(frozen=True) для неизменяемых объектов. Полный перехват доступа дают __setattr__ и __getattribute__, но это уже редкий случай.
Где спотыкаются
Называют __name настоящим приватным атрибутом. Он доступен как obj._Example__name, и интервьюер это сразу покажет.
Ставят двойное подчёркивание на всё подряд. Это мешает наследованию и тестам, в большинстве случаев достаточно одного.
Пишут геттеры и сеттеры в стиле Java (get_name(), set_name()) вместо property. В Python это выглядит чужеродно и лишает возможности начать с простого атрибута, а контроль добавить потом.