Sobes.tech
Назад к вопросам
Junior — Middle
45

Какое отличие между одним и двумя подчеркиваниями в именах переменных или методов?

Ответ от нейросети

sobes.tech AI

Что хотят услышать интервьюеры:

Одинарное подчеркивание обычно означает «внутреннее использование» по соглашению, а двойное — включает механизм name mangling для защиты атрибутов от случайного доступа в наследниках. Это не строгая приватность, а инструмент, уменьшающий риск конфликтов имен. В Python важнее понимать именно соглашение и поведение интерпретатора, а не ожидать настоящего private как в других языках.

Определение:

Одинарное подчеркивание в начале имени, например _name, — это соглашение: такой атрибут или метод считается внутренним и не предназначен для внешнего использования напрямую.

Двойное подчеркивание в начале имени, например __name, запускает name mangling: Python переименовывает атрибут внутри класса, добавляя к нему имя класса. Это помогает избежать случайного переопределения атрибутов в дочерних классах.

Важно: двойное подчеркивание в конце имени, например name__, не имеет специального смысла само по себе; это просто обычное имя.

Пример использования:

class Base:
    def __init__(self):
        self._internal = 1
        self.__secret = 2

    def get_secret(self):
        return self.__secret


class Child(Base):
    def __init__(self):
        super().__init__()
        self.__secret = 99


obj = Child()

print(obj._internal)      # 1
print(obj.get_secret())    # 2

print(obj.__dict__)       # {'_internal': 1, '_Base__secret': 2, '_Child__secret': 99}

Пояснение кода:

Код показывает разницу между _internal и __secret.

_internal — обычный атрибут с соглашением «не использовать снаружи без необходимости». Он доступен напрямую, но по стилю считается внутренним.

__secret в классе Base Python преобразует в _Base__secret. Поэтому в Child атрибут __secret становится уже _Child__secret и не конфликтует с атрибутом родителя.

Из-за этого метод get_secret() в Base возвращает именно значение родительского поля, а не поле дочернего класса.

Ключевые моменты:

  • _name — это соглашение: «внутренний» атрибут или метод.
  • __name — name mangling: Python меняет имя, чтобы снизить риск конфликтов в наследовании.
  • Двойное подчеркивание не делает атрибут полностью приватным.
  • Доступ к __name возможен через преобразованное имя, например _ClassName__name.
  • __name__ с двумя подчеркиваниями с обеих сторон обычно относится к специальным методам Python, а не к приватности.