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