Именование с подчеркиванием в 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.
- Нижнее подчеркивание _: используется как имя для временных переменных.