Именование с подчеркиванием в Python

В Python подчеркивание _ имеет особое значение. Хотя подчеркивание используется просто для переменных и функций snake-case во многих языках, в Python он имеет особое значение. Они широко используются в различных сценариях, включая случаи, когда мы хотим игнорировать некоторое значение, или при объявлении переменных, методов и т.д.

Одиночное и двойное подчеркивание имеет значение в именах переменных и методов Python. Некоторые из этих значений просто условны, а некоторые навязываются интерпретатором Python.

В этой статье мы обсудим пять шаблонов подчеркивания и соглашений об именовании и то, как они влияют на поведение наших программ на Python. Понимание этих концепций очень поможет, особенно при написании сложного кода.

К концу этой заметки мы будем хорошо понимать, как и где использовать тот или иной шаблон подчеркивания в нашем соглашении об именовании. Так что давайте приступим.

1. Одиночный лидирующий символ подчеркивания: _var

Префикс подчеркивания предназначен для подсказки другому программисту, что переменная или метод, начинающийся с одного подчеркивания, предназначен для внутреннего использования. Это соглашение определено в PEP 8.

Имя с префиксом подчеркивания (например,  _spam) должно рассматриваться как непубличная часть API (будь то функция, метод или член данных). Его следует рассматривать как деталь реализации, которая может быть изменена без предварительного уведомления.

Посмотрите на следующий пример:

класс Person:
    def __init__(self):
        self.name = 'Sarah'
        self._age = 26

Давайте инстанцируем вышеуказанный класс и попробуем получить доступ к name и _age атрибутам.

>>> p = Person()
>>> p.name
Сара
>>> p._age
26

Таким образом, одинарный префикс подчеркивания в Python является просто согласованным соглашением и не накладывает никаких ограничений на доступ к значению этой переменной.

2. Двойное ведущее подчеркивание: __var

Использование двойного подчеркивания (__) перед именем (в частности, перед именем метода) не является условностью; оно имеет конкретное значение для интерпретатора.

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

Это также называется менеджмент имен — интерпретатор изменяет имя переменной таким образом, чтобы затруднить возникновение коллизий при последующем расширении класса.

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

класс Person:
    def __init__(self):
        self.name = 'Sarah'
        self._age = 26
        self.__id = 30

Давайте посмотрим на атрибуты его объекта, используя встроенную dir()функцию:

>>> p = Person()
>>> dir(p)
['_Person__id', ..., '_age', 'name']
>>> p.name
Сара
>>> p._age
26
>>>> p.__id
AttributeError: 'Person' объект не имеет атрибута '__id'
>>> p._Person__id
30

Из приведенного выше списка атрибутов объекта видно, что self.name и self._age остаются неизменными и ведут себя так же.

Как бы то ни было, __id искажается до _Person__id. Это изменение имени которое применяет интерпретатор Python. Это делается для защиты переменной от переопределения в подклассах.

Сейчас, если мы создадим подкласс Person, скажем Employee мы не сможем легко переопределить Person’s __id переменную.

class Employee(Person):
    def __init__(self):
        Person.__init__(self)        
        self.__id = 25
>>> emp = Employee()
>>>> dir(emp)
['_Person__id', '_Employee__id', ..., '_age', 'name' ]
>>> emp.__id
AttributeError: 'Employee' object has no attribute '__id' 
>>> emp._Person__id
30
>>> emp._Employee__id
25

Предполагаемое поведение здесь почти эквивалентно финальным переменным в Java и невиртуальным в C++.

3. Одиночный нижний колонтитул: var_

Как объясняется в PEP 8 docs:

Для избежания конфликтов с ключевыми словами Python используется соглашение об именовании с одним подчеркиванием в конце

Когда наиболее подходящее имя для переменной уже занято ключевым словом, для устранения конфликта имен используется соглашение о добавлении одинарного подчеркивания. Типичный пример - использование class или других ключевых слов в качестве переменных.

>>> def method(name, class='Classname'):   #
SyntaxError: "invalid syntax"
>>> def method(name, class_='Classname'):  #
...     pass

4. Двойное ведущее и направляющее подчеркивание: __var__

Имена, имеющие ведущее и последующее двойное подчеркивание (“dunders”), зарезервированы для специального использования, например, для метода__init__ для конструкторов объектов, или __call__ для того, чтобы сделать объект вызываемым. Эти методы известны как dunder методы.

По сути, это просто соглашение, способ для системы Python использовать имена, которые не будут конфликтовать с именами, определенными пользователем. Поэтому dunders - это просто соглашение, и интерпретатор Python его не трогает.

класс Person:
    def __init__(self):
        self.__name__ = 'Sarah'
>>> Person().__name__.
Sarah

В дундеры достигают желаемой цели - делают определенные методы особенными, в то же время делая их такими же, как и другие обычные методы, во всех аспектах, за исключением соглашения об именовании.

Честно говоря, ничто не мешает нам написать собственное dunder (глупость) имя, но лучше не использовать их в наших программах, чтобы избежать столкновений с будущими изменениями в языке Python. (ссылка на статью которая подробно описывает dunders исчерпывающе).

5. Одиночное подчеркивание: _

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

Например, в следующем цикле нам не нужен доступ к бегущему индексу, и мы можем использовать “_”, чтобы указать, что это всего лишь временное значение:

>>> for _ in range(10):
...     print('Welcome Sarah!!!')

Опять же, это значение является “общепринятым”, и в интерпретаторе Python нет никакого специального поведения. Одиночное подчеркивание - это просто допустимое имя переменной, которое&rsquo ; иногда используется для этой цели.

Выводы:

Знание различных underscores паттернов поможет в написании нашего кода более питоническим.

Здесь мы приводим краткое резюме наших 5 шаблонов подчеркивания для соглашений об именовании, которые мы рассмотрели выше.

  • Однострочное подчеркивание _var: соглашение об именовании, указывающее, что имя предназначено для внутреннего использования. Подсказка для программистов и не применяется программистами.
  • Двойной лидирующий символ подчеркивания __var: Вызывает искажение имени при использовании в контексте класса. Применяется интерпретатором Python.
  • Одиночное косое подчеркивание var_: Используется по соглашению, чтобы избежать конфликтов имен с ключевыми словами Python.
  • Двойное подчеркивание в конце __var__: указывает на специальные методы, определенные языком Python.
  • Нижнее подчеркивание _: используется как имя для временных переменных.
Вернуться на верх