5 способов использования подчеркивания (_) в Python

Подчеркиванию (_) в Python отводится особенное место. Если в большинстве других языков оно используется в названиях переменных и функций, то в Python подчеркивание (_) обладает гораздо большей властью. Например, если вы программировали на Python, то вам должен быть знаком следующий синтаксис: for _ in range(10) или __init__(self).

В этой статье мы рассмотрим 5 способов использования (_) в Python:

  1. Хранение значения последнего выражения в интерпретаторе.
  2. Игнорирование некоторых значений.
  3. Задание специальных значений переменным или функциям.
  4. Использование функций «Internationalization(i18n)» и «Localization(l10n)».
  5. Отделение цифр числа друг от друга.

Пройдемся по каждому случаю отдельно.

Хранение значения последнего выражения в интерпретаторе

Интерпретатор Python хранит значение последнего выражения в специальной переменной “_”. Эта возможность сначала использовалась в стандартном CPython-интерпретаторе, но теперь она доступна и в других интерпретаторах.

>>> 10 
10 
>>> _ 
10 
>>> _ * 3 
30 
>>> _ * 20 
600

Игнорирование некоторых значений

Подчеркивание (_) также используется для игнорирования ненужных вам значений.

# Ignore a value when unpacking
x, _, y = (1, 2, 3) # x = 1, y = 3 
# Ignore the multiple values. It is called "Extended Unpacking" which is available in only Python 3.x
x, *_, y = (1, 2, 3, 4, 5) # x = 1, y = 5  
# Ignore the index
for _ in range(10):     
    do_something()  
# Ignore a value of specific location
for _, val in list_of_tuple:
    do_something()

Задание специальных значений для имен переменных или функций

PEP8, руководство по написанию кода на Python, выделяет 4 способа задания имен.

_single_leading_underscore

Таким способом задаются частные переменные, функции, методы и классы в модуле. Все, что использует такой способ задания имени, будет проигнорировано в from module import *.

_internal_name = 'one_nodule' # private variable
_internal_version = '1.0' # private variable

class _Base: # private class
    _hidden_factor = 2 # private variable
    def __init__(self, price):
        self._price = price
    def _double_price(self): # private method
        return self._price * self._hidden_factor
    def get_double_price(self):
        return self._double_price()

single_trailing_underscore_

Такой метод задания имен используется для избежания конфликтов со встроенными именами или классами.

Tkinter.Toplevel(master, class_='ClassName') # Avoid conflict with 'class' keyword

list_ = List.objects.get(1) # Avoid conflict with 'list' built-in type

__double_leading_underscore

Двойное подчеркивание (__) используется для искажения имен атрибутов в классе. Если мы создадим метод с именем «__method» в классе с именем «ClassName», то вызвать этот метод так: «ClassName.__method» — у нас уже не получится. Для дополнительной информации вы можете прочитать о способах задания имен в Python.

class A:
    def _single_method(self):
        pass
    def __double_method(self): # for mangling
        pass
class B(A):
    def __double_method(self): # for mangling
        pass

__double_leading_and_trailing_underscore__

Такой способ именования используется для специальных переменных или функций, таких как __init__ или __len__.

class A:
    def __init__(self, a): # use special method '__init__' for initializing
        self.a = a
    def __custom__(self): # custom special method. you might almost do not use it
        pass

Использование функций «Internationalization(i18n)» и «Localization(l10n)»

# see official docs : https://docs.python.org/3/library/gettext.html
import gettext
gettext.bindtextdomain('myapplication','/path/to/my/language/directory')
gettext.textdomain('myapplication')
_ = gettext.gettext
# ...
print(_('This is a translatable string.'))

Отделение цифр числа друг от друга

Эта возможность была добавлена в Python 3.6. Она позволяет существенно облегчить восприятие и написание больших чисел.

dec_base = 1_000_000
bin_base = 0b_1111_0000
hex_base = 0x_1234_abcd
print(dec_base) # 1000000
print(bin_base) # 240
print(hex_base) # 305441741

Перевод статьи «Understanding the underscore( _ ) of Python»