Подчеркивания в именах Python. Коротко о главном
Без особых углублений в детали давайте разберем главные нюансы в применении подчеркиваний в именах Python. Рассмотрим все часто используемые варианты.
Более детально некоторые аспекты буду освещать в будущих статьях.
1. Игнорирование значений
Игнорирование одного значения
Часто можно встретить запись подобного вида:
for _ in range(2): print("Make repeated action") > Make repeated action > Make repeated action
scheme, _, path = ("https", "t.me", "/python3_with_love") print(scheme, path, sep="\\n") > https > /python3_with_love
В этом случае одно подчеркивание позволяет нам опустить использование имени, когда оно попросту ненужно. По сути, мы просто присваиваем значение символу нижнего подчеркивания и дальше в коде его не используем.
Игнорирование нескольких значений
Кроме того, можно проигнорировать несколько значений, добавив перед одиночным подчеркиванием звездочку, либо указав несколько подчеркиваний через запятую. Простой пример для получения первого и последнего значения из кортежа:
first, *_, last = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) print(first, last, sep="\\n") > 1 > 10
Можем просто перечислить несколько подчеркиваний для игнорирования значений:
scheme, _, _ = ("https", "t.me", "/python3_with_love") print(scheme) > https
2. Подчеркивания перед именем
Одно подчеркивание перед именем
Одно подчеркивание перед именем указывает на то, что объект предназначен для внутреннего использования и вызывать его вне обозначенного класса, модуля или функции не стоит. Можно назвать это псевдо-приватной переменной или методом. “Псевдо” именно потому, что объект возможно вызывать извне, но делать это строго не рекомендуется.
class ExampleClass: _pseudo_private_var = 1 public_var = 2 a = ExampleClass.public_var b = ExampleClass._pseudo_private_var print(a, b) > 2 1
Нам удалось получить доступ к обеим переменным, все значения распечатались без ошибок. Но об использовании приватных объектов нам напомнит IDE:
Кроме того, приватную переменную не подсветит и автокомплит - когда мы напишем ExampleClass.
,в предложенных вариантах мы не увидим нашу приватную переменную.
Для усложнения доступа к приватной переменной нам приходят на помощь 2 нижних подчеркивания.
Два подчеркивания перед именем. Искажения имен
Рассмотрим тот же пример, только добавим еще одну переменную с 2 подчеркиваниями перед именем:
class ExampleClass: __private_var = 0 _pseudo_private_var = 1 public_var = 2 c = ExampleClass.__private_var > AttributeError: type object 'ExampleClass' has no attribute '__private_var'
Вот, другое дело! Теперь вместо доступа к переменной мы получили исключение AttributeError
.
Выглядит действительно как приватный атрибут, но есть 1 нюанс: когда мы указываем 2 подчеркивания перед именем объекта, то используется искажение имен атрибутов класса.
Давайте воспользуемся встроенной функцией dir()
и посмотрим все атрибуты нашего класса:
print(dir(ExampleClass)) > ['_ExampleClass__private_var', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_pseudo_private_var', 'public_var']
Из списка всех атрибутов, найдем созданные нами: _ExampleClass__private_var
, _pseudo_private_var
, public_var
.
Наша приватная переменная теперь с новым именем и именно поэтому мы уже не можем ее вызвать классическим способом ExampleClass.__private_var
.
НО! Все-таки получить значение этой переменной мы можем, если укажем искаженное имя при вызове:
print(ExampleClass._ExampleClass__private_var) > 0
Пусть возможность есть, но делать так не надо. :)
3. Подчеркивания после имени
Одно подчеркивание после имени
Одно подчеркивание после имени следует использовать, когда указанные нами имена совпадают со встроенными, например: type()
, id()
, object()
, …
def _some_func(object, type): return object, type
Следует использовать запись следующего вида:
def _some_func(object_, type_): return object_, type_
4. Двойные подчеркивания до и после имени
Таким образом обозначаются специальные переменные и методы.
Пара примеров использования переменных:
print(__file__) print(__name__) > /Users/me/sources/file_for_test.py > __main__
Специальные методы еще называются магическими (в оригинале - dunder methods) - это отдельный вид искусства в Python.
Примерами таких методов выступают __init__
, __str__
, __repr__
и так далее, их довольно много. Сейчас их разбирать не будем, это целая отдельная тема.
5. Разделение чисел и вывод последнего значения в интерпретаторе
Объединил пару применений в одну группу, как не самые часто используемые и полезные, но тем не менее имеющие свое применение и пользу.
Разделение чисел с помощью подчеркивания
Для удобства чтения числа можно разделять подчеркиванием:
num_1 = 1_000_000_000 num_2 = 1000000000 assert num_1 == num_2
С помощью проверки на равенство значений мы убедились, что num_1
равен num_2
, разница лишь в читаемости.
Вывод последнего значения в интерпретаторе
Ну и если так случилось, что вам необходимо проверить какую-то гипотезу в интерпретаторе, можно воспользоваться одиночным знаком подчеркивания для вывода последнего значения:
> python >>> 10 ** 2 100 >>> _ 100 >>> exit()
Теперь вы знаете, зачем нужны все эти подчеркивания и для чего их применять. Осталось только практиковать.