Какую роль играют префиксы с нижним подчеркиванием в именах методов и атрибутов в Python?

Ответ

В Python префиксы с нижним подчеркиванием (_) в именах переменных, методов и атрибутов используются для указания их области видимости и специального поведения. Это часть соглашений по написанию кода (PEP 8) и механизмов языка.

  1. _single_leading_underscore (одно ведущее подчеркивание)

    • Назначение: Указывает, что переменная или метод предназначены для внутреннего использования внутри модуля или класса. Это соглашение, а не синтаксическое ограничение. Интерпретатор не запрещает доступ к таким атрибутам извне, но это считается дурным тоном.
    • Пример: from module import * не импортирует имена, начинающиеся с _.
      class MyClass:
      def _internal_method(self):
          return "Это внутренний метод класса"
  2. __double_leading_underscore (два ведущих подчеркивания)

    • Назначение: Включает механизм Name Mangling (искажение имен). Интерпретатор автоматически изменяет имя атрибута, чтобы избежать случайных коллизий имен в подклассах.
    • Как работает: Имя __spam внутри класса MyClass будет преобразовано в _MyClass__spam.
      
      class MyClass:
      def __mangled_method(self):
          print("Вызван метод из MyClass")

    class SubClass(MyClass): def __mangled_method(self): print("Вызван метод из SubClass")

    Методы не переопределяют друг друга из-за искажения имен

    obj._MyClassmangled_method() и obj._SubClassmangled_method()

  3. __double_leading_and_trailing_underscore__ (двойные подчеркивания с обеих сторон)

    • Назначение: Зарезервировано для специальных или "магических" методов (dunder methods). Эти методы вызываются Python неявно в определенных ситуациях.
    • Примеры: __init__ (конструктор), __str__ (для str()), __add__ (для оператора +).

      class Number:
      def __init__(self, value):
          self.value = value
      
      def __add__(self, other):
          return self.value + other.value
  4. single_trailing_underscore_ (одно подчеркивание в конце)

    • Назначение: Используется по соглашению, чтобы избежать конфликтов с ключевыми словами Python.
      # Нельзя: def my_func(class):
      # Можно:
      def my_func(class_):
      print(class_)