6. Выражения

Эта глава объясняет значение элементов выражений в Python.

Замечания о синтаксисе: В этой и следующих главах для описания синтаксиса, а не лексического анализа, используется грамматическая нотация.

Если (один из вариантов) правила синтаксиса имеет вид:

name: othername

и никакая семантика не задана, то семантика этой формы name такая же, как у othername.

6.1. Арифметические преобразования

Когда в описании арифметического оператора ниже используется фраза «числовые аргументы преобразуются к общему вещественному типу», это означает, что реализация оператора для встроенных числовых типов работает так, как описано в разделе Числовые типы документации стандартной библиотеки.

Для некоторых операторов и нечисловых операндов (например, строк в качестве левого аргумента оператора %) действуют дополнительные правила. Расширения должны сами определять своё поведение при преобразовании.

6.2. Элементарные выражения

Элементарные выражения — это самые базовые элементы выражений. Простейшие из них — встроенные константы, имена и литералы. Более сложные заключаются в парные разделители:

Формально синтаксис элементарных выражений выглядит так:

atom:
   | builtin_constant
   | identifier
   | literal
   | parenthesized_enclosure
   | bracketed_enclosure
   | braced_enclosure
parenthesized_enclosure:
   | group
   | tuple
   | yield_atom
   | generator_expression
bracketed_enclosure:
   | listcomp
   | list
braced_enclosure:
   | dictcomp
   | dict
   | setcomp
   | set

6.2.1. Встроенные константы

Ключевые слова True, False и None обозначают встроенные константы. Токен ... обозначает константу Ellipsis.

Вычисление этих элементарных выражений даёт соответствующее значение.

Примечание

Ещё несколько встроенных констант доступны как глобальные переменные, но ключевыми словами являются только упомянутые здесь. В частности, эти имена нельзя переприсваивать или использовать в качестве атрибутов:

>>> False = 123
  File "<input>", line 1
   False = 123
   ^^^^^
SyntaxError: cannot assign to False

Формально синтаксис встроенных констант выглядит так:

builtin_constant: 'True' | 'False' | 'None' | '...'

6.2.2. Идентификаторы (имена)

Идентификатор, встречающийся в роли элементарного выражения, является именем. Лексическое определение см. в разделе Имена (идентификаторы и ключевые слова), а описание именования и связывания — в разделе Именование и связывание.

Когда имя связано с объектом, вычисление элементарного выражения даёт этот объект. Если имя не связано, попытка его вычислить возбуждает исключение NameError.

6.2.2.1. Искажение закрытых имён

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

Точнее, перед генерацией кода закрытые имена преобразуются в более длинную форму. Если преобразованное имя длиннее 255 символов, может произойти усечение, определяемое реализацией.

Преобразование не зависит от синтаксического контекста, в котором используется идентификатор, но искажаются только следующие закрытые идентификаторы:

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

    Атрибут __name__ вложенных функций, классов и псевдонимов типов при этом не искажается.

  • Имя импортируемого модуля, например __spam в import __spam. Если модуль входит в пакет (то есть его имя содержит точку), имя не искажается, например __foo в import __foo.bar не искажается.

  • Имя импортируемого члена, например __f в from spam import __f.

Правило преобразования определено следующим образом:

  • Перед идентификатором вставляется имя класса, у которого сперва удалены все ведущие подчёркивания, а затем добавлено одно. Например, идентификатор __spam в классе с именем Foo, _Foo или __Foo преобразуется в _Foo__spam.

  • Если имя класса состоит только из подчёркиваний, преобразование никак не изменяет идентификатор. Например, идентификатор __spam в классе с именем _ или __ остаётся без изменений.

6.2.3. Литералы

Литерал — это текстовое представление значения. Python поддерживает числовые, строковые и байтовые литералы. Форматированные строки и шаблонные строки считаются строковыми литералами.

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

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

Обратите внимание: отрицательные и комплексные числа, такие как -3 или 3+4.2j, синтаксически не являются литералами. Это унарные или бинарные арифметические операции с операторами - или +.

Вычисление литерала даёт объект заданного типа (int, float, complex, str, bytes или Template) с заданным значением. Для литералов с плавающей точкой и мнимых литералов значение может быть приближённым.

Формальная грамматика литералов:

literal: strings | NUMBER

6.2.3.1. Литералы и тождественность объектов

Все литералы соответствуют неизменяемым типам данных, поэтому идентичность объекта менее важна, чем его значение. Многократные вычисления литералов с одним и тем же значением (будь то одно и то же вхождение в тексте программы или разные) могут давать один и тот же объект или разные объекты с одинаковым значением.

Особенность реализации CPython

Например, в CPython малые целые числа с одинаковым значением вычисляются в один и тот же объект:

>>> x = 7
>>> y = 7
>>> x is y
True

Однако большие целые числа вычисляются в разные объекты:

>>> x = 123456789
>>> y = 123456789
>>> x is y
False

Это поведение может измениться в будущих версиях CPython. В частности, граница между «малыми» и «большими» целыми числами уже менялась в прошлом.

CPython выдаст SyntaxWarning при сравнении литералов с помощью is:

>>> x = 7
>>> x is 7
<input>:1: SyntaxWarning: "is" with 'int' literal. Did you mean "=="?
True

См. When can I rely on identity tests with the is operator? для дополнительной информации.

Шаблонные строки неизменяемы, но могут ссылаться на изменяемые объекты как значения Interpolation. В рамках этого раздела две t-строки имеют «одинаковое значение», если совпадают и их структура, и идентичность значений.

В настоящее время каждое вычисление шаблонной строки даёт новый объект.

6.2.3.2. Конкатенация строковых литералов

Несколько расположенных рядом строковых или байтовых литералов, возможно, с разными способами записи кавычек, допускаются, и их значение совпадает с их конкатенацией:

>>> "привет" 'мир'
"приветмир"

Эта возможность определена на синтаксическом уровне, поэтому работает только с литералами. Для конкатенации строковых выражений во время выполнения можно использовать оператор „+“:

>>> greeting = "Привет"
>>> space = " "
>>> name = "Блез"
>>> print(greeting + space + name)   # а не: print(greeting space name)
Привет Блез

Конкатенация литералов позволяет свободно смешивать сырые строки, строки в тройных кавычках и форматированные строковые литералы. Например:

>>> "Привет" r', ' f"{name}!"
"Привет, Блез!"

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

re.compile("[A-Za-z_]"       # буква или подчёркивание
           "[A-Za-z0-9_]*"   # буква, цифра или подчёркивание
          )

Однако байтовые литералы можно объединять только с другими байтовыми литералами, но не со строковыми литералами любого вида. Также шаблонные строковые литералы можно объединять только с другими шаблонными строковыми литералами:

>>> t"Привет" t"{name}!"
Template(strings=('Привет', '!'), interpolations=(...))

Формально:

strings: (STRING | fstring)+ | tstring+

6.2.4. Группы в скобках

Группа в скобках — это выражение, заключённое в круглые скобки. Группа вычисляется в то же значение, что и выражение внутри.

Группы используются для переопределения или уточнения приоритета операторов, как и в математической записи. Например:

>>> 3 << 2 | 4
12
>>> 3 << (2 | 4)   # Переопределение приоритета оператора | (побитовое ИЛИ)
192
>>> (3 << 2) | 4   # То же, что и без скобок (но яснее)
12

Обратите внимание: не всё, что заключено в скобки, является группой. В частности, группа в скобках должна содержать ровно одно выражение и не может заканчиваться запятой. Другие формы записи в скобках см. в разделах явные представления кортежей и генераторные выражения.

Формально синтаксис групп выглядит так:

group: '(' assignment_expression ')'

6.2.5. Явные представления контейнеров

Для создания встроенных контейнеров (списков, множеств, кортежей или словарей) Python предоставляет специальный синтаксис, называемый явными представлениями. Между четырьмя видами явных представлений есть тонкие различия, описанные в следующих разделах. Однако все явные представления состоят из элементов, разделённых запятыми и заключённых в парные разделители.

Например, явное представление списка — это набор выражений в квадратных скобках:

>>> ["один", "два", "три"]
['один', 'два', 'три']
>>> [1 + 2, 2 + 3]
[3, 5]

В явных представлениях списков, кортежей и словарей (но не множеств) набор может быть пустым:

>>> []  # пустой список
[]
>>> ()  # пустой кортеж
()
>>> {}  # пустой словарь
{}

Если набор не пуст, после элементов может стоять дополнительная запятая, которая ни на что не влияет:

>>> ["один", "два", "три",]  # обратите внимание на запятую после "три"
['один', 'два', 'три']

Примечание

Завершающая запятая часто используется в явных представлениях, занимающих несколько строк (с помощью неявного объединения строк), чтобы будущему программисту, добавляющему новую запись в конец, не приходилось изменять уже существующую строку:

>>> [
...     'один',
...     'два',
...     'три',
... ]
['один', 'два', 'три']

Во время выполнения при вычислении явного представления перечисленные элементы вычисляются слева направо и помещаются в новый контейнер соответствующего типа.

Для явных представлений кортежей, списков и множеств (но не словарей) любому элементу может предшествовать звёздочка (*). Это обозначает распаковку итерируемых объектов. Во время выполнения выражение со звёздочкой должно вычисляться в итерируемый объект, содержимое которого вставляется в контейнер на месте распаковки. Например:

>>> numbers = (1, 2)
>>> [*numbers, 'слово', *numbers]
[1, 2, 'слово', 1, 2]

Явные представления словарей используют похожий механизм, называемый распаковкой словаря и обозначаемый двойной звёздочкой (**). Подробности см. в разделе Явные представления словарей.

Более продвинутая форма явных представлений — включения, в которых элементы вычисляются набором инструкций цикла и фильтрации. Подробности см. в разделе Включения.

Добавлено в версии 3.5: Распаковка итерируемых объектов и словарей в явных представлениях, изначально предложенная в PEP 448.

6.2.5.1. Явные представления списков

Явное представление списка — это, возможно, пустой набор выражений в квадратных скобках. Например:

>>> ["один", "два", "три"]
['один', 'два', 'три']
>>> ["один"]  # список из одного элемента
['один']
>>> []       # пустой список
[]

Общие сведения о явных представлениях см. в разделе Явные представления контейнеров.

Формальная грамматика явных представлений списков:

list: '[' [flexible_expression_list] ']'

6.2.5.2. Явные представления множеств

Явное представление множества — это непустой набор выражений в фигурных скобках. Например:

>>> {"один", "два", "три"}
{'один', 'три', 'два'}
>>> {"один"}  # множество из одного элемента
{'one'}

Общие сведения о явных представлениях см. в разделе Явные представления контейнеров.

Специального синтаксиса для пустого множества нет. Литерал {} — это явное представление словаря, создающее пустой словарь. Чтобы получить пустое множество, вызовите set() без аргументов.

Формальная грамматика явных представлений множеств:

set: '{' flexible_expression_list '}'

6.2.5.3. Явные представления кортежей

Явное представление кортежа — это набор выражений в круглых скобках. Например:

>>> (1, 2)
(1, 2)
>>> ()  # пустой кортеж
()

Общие сведения о явных представлениях см. в разделе Явные представления контейнеров.

Чтобы избежать неоднозначности, если в явном представлении кортежа ровно один элемент, требуется завершающая запятая. Без неё получится группа в скобках:

>>> ('единственный',)  # кортеж из одного элемента
('единственный',)
>>> ('единственный')   # нет запятой: одна строка
'единственный'

Иными словами, явное представление кортежа — это заключённый в скобки список, который состоит либо из:

  • двух или более выражений, разделённых запятыми, либо

  • нуля или более выражений, за каждым из которых стоит запятая.

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

Примечание

Синтаксис Python также включает списки выражений, в которых список выражений, разделённых запятыми, не заключён в скобки, но вычисляется в кортеж.

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

Формальная грамматика явных представлений кортежей:

tuple:
   | '(' flexible_expression (',' flexible_expression)+ [','] ')'
   | '(' flexible_expression ',' ')'
   | '(' ')'

6.2.5.4. Явные представления словарей

Явное представление словаря — это, возможно, пустой набор элементов словаря, заключённый в фигурные скобки. Каждый элемент словаря — это пара выражений, разделённых двоеточием: ключ и связанное с ним значение. Например:

>>> {1: 'один', 2: 'два'}
{1: 'один', 2: 'два'}

Во время выполнения при вычислении явного представления словаря выражения вычисляются слева направо. Каждый объект-ключ используется как ключ в словаре для сохранения соответствующего значения. Это означает, что в представлении можно указать один и тот же ключ несколько раз, и итоговое значение в словаре для данного ключа будет последним из указанных. Например:

>>> {
...     1: 'это будет переопределено',
...     2: 'два',
...     1: 'это тоже переопределено',
...     1: 'один',
... }
{1: 'один', 2: 'два'}

Вместо пары «ключ — значение» элементом словаря может быть выражение с префиксом в виде двойной звёздочки **. Это обозначает распаковку словаря. Во время выполнения такое выражение должно вычисляться в отображение; каждый элемент отображения добавляется в новый словарь. Как и в случае пар «ключ — значение», более поздние значения заменяют значения, уже заданные более ранними элементами и распаковками. Так можно переопределить набор значений по умолчанию:

>>> defaults = {'цвет': 'синий', 'количество': 8}
>>> overrides = {'цвет': 'жёлтый'}
>>> {**defaults, **overrides}
{'цвет': 'жёлтый', 'количество': 8}

Добавлено в версии 3.5: Распаковка в явные представления словарей, изначально предложенная в PEP 448.

Формальная грамматика явных представлений словарей:

dict:                   '{' [double_starred_kvpairs] '}'
double_starred_kvpairs: ','.double_starred_kvpair+ [',']
double_starred_kvpair:  '**' or_expr | kvpair
kvpair:                 expression ':' expression

6.2.6. Включения

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

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

Например, список первых десяти квадратов выглядит так:

>>> [x**2 for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Во время выполнения включение списка создаёт новый список. Выражение после in должно вычисляться в итерируемый объект. Каждый элемент этого итерируемого объекта связывается с целью части for, как в инструкции for, затем вычисляется выражение перед for, в котором можно использовать эту цель, а результат добавляется в новый список. Таким образом, пример выше примерно эквивалентен определению и вызову следующей функции:

def make_list_of_squares(iterable):
    result = []
    for x in iterable:
        result.append(x**2)
    return result

make_list_of_squares(range(10))

Включения множеств работают аналогично. Например, вот множество строчных букв:

>>> {x.lower() for x in ['a', 'A', 'b', 'C']}
{'c', 'a', 'b'}

Во время выполнения это примерно соответствует вызову такой функции:

def make_lowercase_set(iterable):
    result = set()
    for x in iterable:
        result.add(x.lower())
    return result

make_lowercase_set(['a', 'A', 'b', 'C'])

Включения словарей начинаются с пары «ключ — значение», разделённой двоеточием, вместо выражения. Например:

>>> {func.__name__: func for func in [print, hex, any]}
{'print': <built-in function print>,
 'hex': <built-in function hex>,
 'any': <built-in function any>}

Во время выполнения это примерно соответствует следующему:

def make_dict_mapping_names_to_functions(iterable):
    result = {}
    for func in iterable:
        result[func.__name__] = func
    return result

make_dict_mapping_names_to_functions([print, hex, any])

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

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

>>> tuple(x**2 for x in range(10))
(0, 1, 4, 9, 16, 25, 36, 49, 64, 81)

Изменено в версии 3.8: До Python 3.8 порядок вычисления ключа и значения во включениях словарей не был строго определён. В CPython значение вычислялось раньше ключа. Начиная с версии 3.8 ключ вычисляется раньше значения, как предложено в PEP 572.

6.2.6.1. Фильтрация во включениях

За частью for может следовать часть if с выражением.

Например, список имён из модуля math, начинающихся с f, выглядит так:

>>> [name for name in vars(math) if name.startswith('f')]
['fabs', 'factorial', 'floor', 'fma', 'fmod', 'frexp', 'fsum']

Во время выполнения выражение после if вычисляется перед добавлением каждого элемента в результирующий контейнер, и если оно ложно, элемент пропускается. Таким образом, пример выше примерно соответствует определению и вызову следующей функции:

def get_math_f_names(iterable):
    result = []
    for name in iterable:
        if name.startswith('f'):
           result.append(name)
    return result

get_math_f_names(vars(math))

Фильтрация — это частный случай более сложных включений. Более формальное описание см. в следующем разделе.

6.2.6.2. Сложные включения

В общем случае за начальной частью for включения может идти любое число дополнительных частей for или if. Например, вот список имён из двух модулей Python, отфильтрованный так, чтобы в него вошли только имена, начинающиеся с a:

>>> import array
>>> import math
>>> [
...     name
...     for module in [array, math]
...     for name in vars(module)
...     if name.startswith('a')
... ]
['array', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh']

Во время выполнения это примерно соответствует определению и вызову следующей функции:

def get_a_names(iterable):
    result = []
    for module in iterable:
        for name in vars(module):
            if name.startswith('a'):
                result.append(name)
    return result

get_a_names([array, math])

Элементами нового контейнера становятся те значения, что получились бы, если считать каждую из частей for или if блоком, вложенным слева направо, и вычислять выражение для получения элемента (или записи словаря) каждый раз, когда достигается самый внутренний блок.

За исключением итерируемого выражения в самой левой части for, включение выполняется в отдельной неявно вложенной области видимости. Это гарантирует, что имена, которым присваиваются значения в списке целей, не «просачиваются» в охватывающую область видимости. Например:

>>> x = 'старое значение'
>>> [x**2 for x in range(10)]  # этот `x` локален для включения
>>> x
'старое значение'

Итерируемое выражение в самой левой части for вычисляется непосредственно в охватывающей области видимости, а затем передаётся как аргумент в неявно вложенную область видимости.

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

Чтобы включение всегда давало контейнер соответствующего типа, выражения yield и yield from запрещены в неявно вложенной области видимости.

Выражения присваивания не допускаются внутри итерируемых выражений включений (то есть выражений после ключевого слова in), а также в любом месте включений, находящихся непосредственно в определении класса.

Изменено в версии 3.8: Теперь yield и yield from запрещены в неявно вложенной области видимости.

6.2.6.3. Распаковка во включениях

Если выражение включения списка или множества записано со звёздочкой, результат будет распакован, чтобы получить любое число элементов (в том числе ни одного).

Это часто используется для «уплощения» списков, например:

>>> students = ['Пётр', 'Блез', 'Ярка']
>>> teachers = ['Салим', 'Бартош']
>>> lists_of_people = [students, teachers]
>>> [*people for people in lists_of_people]
['Пётр', 'Блез', 'Ярка', 'Салим', 'Бартош']

Во время выполнения это включение примерно соответствует:

def flatten_names(lists_of_people):
    result = []
    for people in lists_of_people:
        result.extend(people)
    return result

Во включениях словарей выражение с двойной звёздочкой вычисляется, а затем распаковывается с помощью распаковки словаря, вставляя в новый словарь любое число пар «ключ — значение» (в том числе ни одной). Как и в других видах явных представлений словарей, если один и тот же ключ указан несколько раз, в итоговом словаре с ним будет связано значение, указанное последним.

Например:

>>> system_defaults = {'цвет': 'синий', 'количество': 8}
>>> user_defaults = {'цвет': 'жёлтый'}
>>> overrides = {'количество': 5}

>>> configuration_sets = [system_defaults, user_defaults, overrides]

>>> {**d for d in configuration_sets}
{'цвет': 'жёлтый', 'количество': 5}

Добавлено в версии 3.15: Распаковка во включениях с помощью операторов * и ** была представлена в PEP 798.

6.2.6.4. Асинхронные включения

В функции async def часть async for может использоваться для перебора элементов асинхронного итератора. Включение в функции async def может состоять из части for или async for после начального выражения, может содержать дополнительные части for или async for, а также может использовать выражения await.

Если включение содержит части async for или содержит выражения await либо другие асинхронные включения где-либо, кроме итерируемого выражения в самой левой части for, оно называется асинхронным включением. Асинхронное включение может приостанавливать выполнение сопрограммной функции, в которой оно находится.

Добавлено в версии 3.6: Асинхронные включения были представлены в PEP 530.

Изменено в версии 3.11: Теперь асинхронные включения разрешены внутри включений в асинхронных функциях. Внешние включения неявно становятся асинхронными.

6.2.6.5. Формальная грамматика включений

Формальная грамматика включений выглядит так:

listcomp:      '[' comprehension ']'
setcomp:       '{' comprehension '}'
comprehension: flexible_expression for_if_clause+

dictcomp:
    | '{' kvpair for_if_clause+ '}'
    | '{' '**' expression for_if_clause+ '}'

for_if_clause:
    | ['async'] 'for' target_list 'in' or_test ('if' or_test)*

6.2.7. Генераторные выражения

Синтаксис генераторных выражений такой же, как у включений списков, за тем исключением, что они заключаются в круглые скобки, а не в квадратные. Например:

>>> iterator = (x ** 2 for x in range(10))
>>> iterator
<generator object <genexpr> at ...>

Во время выполнения генераторное выражение вычисляется в генераторный итератор, который выдаёт те же значения, что и соответствующее включение списка:

>>> list(iterator)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Таким образом, пример выше примерно эквивалентен определению и вызову следующей генераторной функции:

def make_generator_of_squares(iterator):
    for x in iterator:
        yield x ** 2

make_generator_of_squares(iter(range(10)))

Скобки вокруг генераторного выражения можно опустить в вызовах, если оно — единственный позиционный аргумент и именованных аргументов нет. Подробности см. в разделе «Вызовы». Например:

# Скобки после `sum` — часть синтаксиса вызова:
>>> sum(x ** 2 for x in range(10))
285

# Генератору нужны собственные скобки, если он не единственный аргумент:
>>> sum((x ** 2 for x in range(10)), start=1000)
1285

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

>>> (x ** 2 for x in nonexistent_iterable)
Traceback (most recent call last):
  ...
NameError: name 'nonexistent_iterable' is not defined

После вычисления выражения из его результата создаётся итератор, как если бы для него была вызвана iter(). Любая ошибка, возбуждаемая при создании итератора, также возникает немедленно:

>>> (x ** 2 for x in None)
Traceback (most recent call last):
  ...
TypeError: 'NoneType' object is not iterable

Все остальные выражения вычисляются лениво, так же, как в обычных генераторах (то есть когда итератор просят выдать значение):

>>> iterator = (nonexistent_value for x in range(10))
>>> iterator
<generator object <genexpr> at ...>
>>> list(iterator)
Traceback (most recent call last):
  ...
NameError: name 'nonexistent_value' is not defined
>>> iterator = (x * y for x in range(10) for y in nonexistent_iterable)
>>> iterator
<generator object <genexpr> at ...>
>>> list(iterator)
Traceback (most recent call last):
  ...
NameError: name 'nonexistent_iterable' is not defined

Чтобы не нарушать ожидаемую работу самого генераторного выражения, выражения yield и yield from запрещены внутри неявно вложенной области видимости.

Если генераторное выражение содержит либо части async for, либо выражения await, оно называется асинхронным генераторным выражением. Асинхронное генераторное выражение возвращает новый объект асинхронного генератора, который является асинхронным итератором (см. Асинхронные итераторы).

Формальная грамматика генераторных выражений:

generator_expression: "(" comprehension ")"

Добавлено в версии 3.6: Были представлены асинхронные генераторные выражения.

Изменено в версии 3.7: До Python 3.7 асинхронные генераторные выражения могли появляться только в сопрограммах async def. Начиная с версии 3.7 асинхронные генераторные выражения могут использоваться в любой функции.

Изменено в версии 3.8: Теперь yield и yield from запрещены в неявно вложенной области видимости.

6.2.8. Выражения yield

yield_atom:       "(" yield_expression ")"
yield_from:       "yield" "from" expression
yield_expression: "yield" yield_list | yield_from

Выражение yield используется при определении генераторной функции или асинхронной генераторной функции, и поэтому его можно использовать только в теле определения функции. Использование выражения yield в теле функции делает эту функцию генераторной, а его использование в теле функции async def делает эту сопрограммную функцию асинхронной генераторной функцией. Например:

def gen():  # определяет генераторную функцию
    yield 123

async def agen(): # определяет асинхронную генераторную функцию
    yield 123

Из-за побочных эффектов, оказываемых на содержащую их область видимости, выражения yield не допускаются в неявно определяемых областях видимости, которые используются для реализации включений и генераторных выражений.

Изменено в версии 3.8: Теперь выражения yield запрещены в неявно вложенных областях видимости, используемых для реализации включений и генераторных выражений.

Генераторные функции описаны ниже, в то время как асинхронные генераторные функции описаны отдельно в разделе Асинхронные генераторные функции.

При вызове генераторной функции она возвращает итератор, называемый генератором. Этот генератор затем управляет выполнением генераторной функции. Выполнение начинается при вызове одного из методов генератора. В этот момент выполнение доходит до первого выражения yield, где снова приостанавливается, возвращая вызывающей стороне генератора значение yield_list или None, если yield_list опущен. Под приостановкой понимается, что сохраняется всё локальное состояние: текущие привязки локальных переменных, указатель инструкций, внутренний стек вычислений и состояние обработки любых исключений. Когда выполнение возобновляется вызовом одного из методов генератора, функция может продолжить работу точно так, как если бы выражение yield было обычным внешним вызовом. Значение выражения yield после возобновления зависит от метода, который возобновил выполнение. Если используется __next__() (обычно через for или встроенную функцию next()), результат равен None. В противном случае, если используется send(), результатом будет значение, переданное в этот метод.

Всё это делает генераторные функции очень похожими на сопрограммы: они выдают значения несколько раз, у них больше одной точки входа, и их выполнение можно приостанавливать. Единственное отличие в том, что генераторная функция не может управлять тем, где должно продолжиться выполнение после выдачи значения: управление всегда передаётся вызывающей стороне генератора.

Выражения yield разрешены в любом месте конструкции try. Если генератор не возобновляется до его финализации (при достижении нулевого счётчика ссылок или при сборке мусора), вызывается метод close() генераторного итератора, что позволяет выполниться всем ожидающим частям finally.

При использовании yield from <expr> переданное выражение должно быть итерируемым объектом. Значения, получаемые при переборе этого итерируемого объекта, передаются напрямую тому, кто вызывает методы текущего генератора. Любые значения, переданные с помощью send(), и любые исключения, переданные с помощью throw(), передаются вложенному итератору, если у него есть соответствующие методы. В противном случае send() возбудит AttributeError или TypeError, а throw() просто немедленно возбудит переданное исключение.

Когда вложенный итератор завершается, атрибут value возбуждённого экземпляра StopIteration становится значением выражения yield. Это значение можно задать явно при возбуждении StopIteration или автоматически, если подитератор является генератором (возвратом значения из подгенератора).

Изменено в версии 3.3: Добавлено выражение yield from <expr>, которое делегирует поток управления подитератору.

Теперь скобки можно опустить, если выражение yield — единственное выражение в правой части инструкции присваивания.

См. также

PEP 255 — Простые генераторы

Предложение о добавлении в Python генераторов и инструкции yield.

PEP 342 — Сопрограммы через расширенные генераторы

Предложение расширить API и синтаксис генераторов, чтобы их можно было использовать как простые сопрограммы.

PEP 380 — Синтаксис делегирования подгенератору

Предложение добавить синтаксис yield_from, упрощающий делегирование подгенераторам.

PEP 525 — Асинхронные генераторы

Предложение, которое расширило PEP 492, добавив возможности генераторов в сопрограммные функции.

6.2.8.1. Примеры

Вот простой пример, демонстрирующий поведение генераторов и генераторных функций:

>>> def echo(value=None):
...     print("Выполнение начинается, когда 'next()' вызывается в первый раз.")
...     try:
...         while True:
...             try:
...                 value = (yield value)
...             except Exception as e:
...                 value = e
...     finally:
...         print("Не забудьте выполнить очистку при вызове 'close()'.")
...
>>> generator = echo(1)
>>> print(next(generator))
Выполнение начинается, когда 'next()' вызывается в первый раз.
1
>>> print(next(generator))
None
>>> print(generator.send(2))
2
>>> generator.throw(TypeError, "spam")
TypeError('spam',)
>>> generator.close()
Не забудьте выполнить очистку при вызове 'close()'.

Примеры использования yield from см. в PEP 380: Syntax for Delegating to a Subgenerator в разделе «Что нового в Python».

6.2.8.2. Асинхронные генераторные функции

Наличие выражения yield в функции или методе, определённых с помощью async def, делает эту функцию асинхронной генераторной.

При вызове асинхронной генераторной функции она возвращает асинхронный итератор, называемый объектом асинхронного генератора. Этот объект затем управляет выполнением генераторной функции. Объект асинхронного генератора обычно используется в циклической инструкции async for в сопрограммной функции аналогично тому, как объект генератора используется в инструкции for.

Вызов одного из методов асинхронного генератора возвращает ожидаемый объект, и выполнение начинается, когда этот объект ожидается с помощью await. В этот момент выполнение доходит до первого выражения yield, где снова приостанавливается, возвращая значение yield_list ожидающей сопрограмме. Как и в случае генератора, приостановка означает, что сохраняется всё локальное состояние: текущие привязки локальных переменных, указатель инструкций, внутренний стек вычислений и состояние обработки любых исключений. Когда выполнение возобновляется ожиданием следующего объекта, возвращённого методами асинхронного генератора, функция может продолжить работу точно так, как если бы выражение yield было обычным внешним вызовом. Значение выражения yield после возобновления зависит от метода, который возобновил выполнение. Если используется __anext__(), результат равен None. В противном случае, если используется asend(), результатом будет значение, переданное в этот метод.

Если асинхронный генератор досрочно завершается из-за break, отмены вызывающей задачи или других исключений, код асинхронной очистки генератора будет выполнен и, возможно, возбудит исключения или обратится к контекстным переменным в неожиданном контексте — например, после окончания жизни задач, от которых он зависит, или во время остановки цикла событий, когда вызывается обработчик сборки мусора для асинхронных генераторов. Чтобы этого избежать, вызывающая сторона должна явно закрыть асинхронный генератор, вызвав метод aclose(), чтобы завершить генератор и в итоге отсоединить его от цикла событий.

В асинхронной генераторной функции выражения yield разрешены в любом месте конструкции try. Однако если асинхронный генератор не возобновляется до его финализации (при достижении нулевого счётчика ссылок или при сборке мусора), выражение yield внутри конструкции try может привести к невыполнению ожидающих частей finally. В этом случае ответственность лежит на цикле событий или планировщике, выполняющем асинхронный генератор: они должны вызвать метод aclose() асинхронного генераторного итератора и запустить полученный объект сопрограммы, что позволит выполниться всем ожидающим частям finally.

Чтобы обеспечить финализацию при завершении работы цикла событий, цикл событий должен определить функцию-финализатор, которая принимает асинхронный генераторный итератор и, как ожидается, вызывает aclose() и выполняет сопрограмму. Этот финализатор можно зарегистрировать вызовом sys.set_asyncgen_hooks(). При первом переборе элементов асинхронный генераторный итератор сохраняет зарегистрированный финализатор, который будет вызван при финализации. Образец финализатора см. в реализации asyncio.BaseEventLoop._asyncgen_finalizer_hook в Lib/asyncio/base_events.py.

Выражение yield from <expr> является синтаксической ошибкой при использовании в асинхронной генераторной функции.

6.3. Первичные выражения

Первичные выражения представляют операции языка с самым высоким приоритетом. Их синтаксис:

primary: atom | attributeref | subscription | call

6.3.1. Обращения к атрибутам

Обращение к атрибуту — это первичное выражение, за которым следуют точка и имя:

attributeref: primary "." identifier

Первичное выражение должно вычисляться в объект типа, поддерживающего обращения к атрибутам, что и делает большинство объектов. Затем у этого объекта запрашивается атрибут, имя которого задано идентификатором. Тип и значение результата определяет сам объект. Многократные вычисления одного и того же обращения к атрибуту могут давать разные объекты.

Поведение такого обращения можно настроить, переопределив метод __getattribute__() или метод __getattr__(). Сначала вызывается метод __getattribute__(), который либо возвращает значение, либо возбуждает AttributeError, если атрибут недоступен.

Если возникает AttributeError и у объекта есть метод __getattr__(), то он вызывается как запасной вариант.

6.3.2. Индексирование и срезы

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

>>> digits_by_name = {'один': 1, 'два': 2}
>>> digits_by_name['два']  # Индексирование словаря по ключу 'два'
2

В синтаксисе индексирования за индексируемым объектом — первичным выражением — следует индексатор в квадратных скобках. В простейшем случае индексатор — одно выражение.

В зависимости от типа индексируемого объекта индексатор иногда называют ключом (для отображений), индексом (для последовательностей) или аргументом типа (для обобщённых типов). Синтаксически все они эквивалентны:

>>> colors = ['красный', 'синий', 'зелёный', 'чёрный']
>>> colors[3]  # Индексирование списка по индексу 3
'чёрный'

>>> list[str]  # Параметризация типа list аргументом типа str
list[str]

Во время выполнения интерпретатор вычисляет первичное выражение и индексатор и вызывает специальный метод первичного выражения __getitem__() или __class_getitem__(), передавая ему индексатор в качестве аргумента. Подробнее о том, какой из этих методов вызывается, см. в __class_getitem__ против __getitem__.

Чтобы показать, как работает индексирование, можно определить собственный объект, реализующий __getitem__() и выводящий значение индексатора:

>>> class SubscriptionDemo:
...     def __getitem__(self, key):
...         print(f'обращение по индексатору: {key!r}')
...
>>> demo = SubscriptionDemo()
>>> demo[1]
обращение по индексатору: 1
>>> demo['а' * 3]
обращение по индексатору: 'ааа'

О том, как встроенные типы обрабатывают индексирование, см. в документации __getitem__().

Индексирование может также использоваться как цель в инструкциях присваивания или удаления. В этих случаях интерпретатор вызывает у индексируемого объекта специальный метод __setitem__() или __delitem__() соответственно вместо __getitem__().

>>> colors = ['красный', 'синий', 'зелёный', 'чёрный']
>>> colors[3] = 'белый'  # Установка элемента по индексу
>>> colors
['красный', 'синий', 'зелёный', 'белый']
>>> del colors[3]  # Удаление элемента с индексом 3
>>> colors
['красный', 'синий', 'зелёный']

Все продвинутые формы индексатора, описанные в следующих разделах, также можно использовать для присваивания и удаления.

6.3.2.1. Срезы

Более продвинутая форма индексирования, получение среза, обычно используется для извлечения части последовательности. В этой форме индексатор — это срез: до трёх выражений, разделённых двоеточиями. Любое из выражений можно опустить, но срез должен содержать хотя бы одно двоеточие:

>>> number_names = ['ноль', 'один', 'два', 'три', 'четыре', 'пять']
>>> number_names[1:3]
['один', 'два']
>>> number_names[1:]
['один', 'два', 'три', 'четыре', 'пять']
>>> number_names[:3]
['ноль', 'один', 'два']
>>> number_names[:]
['ноль', 'один', 'два', 'три', 'четыре', 'пять']
>>> number_names[::2]
['ноль', 'два', 'четыре']
>>> number_names[:-3]
['ноль', 'один', 'два']
>>> del number_names[4:]
>>> number_names
['ноль', 'один', 'два', 'три']

При вычислении среза интерпретатор создаёт объект slice, у которого атрибуты start, stop и step соответственно равны результатам выражений между двоеточиями. Любое отсутствующее выражение вычисляется в None. Затем этот объект slice передаётся специальному методу __getitem__() или __class_getitem__(), как и выше.

# продолжение с экземпляром SubscriptionDemo, определённым выше:
>>> demo[2:3]
обращение по индексатору: slice(2, 3, None)
>>> demo[::'spam']
обращение по индексатору: slice(None, None, 'spam')

6.3.2.2. Индексаторы, разделённые запятыми

Индексатор также может задаваться как два или более выражений или срезов, разделённых запятыми:

# продолжение с экземпляром SubscriptionDemo, определённым выше:
>>> demo[1, 2, 3]
обращение по индексатору: (1, 2, 3)
>>> demo[1:2, 3]
обращение по индексатору: (slice(1, 2, None), 3)

Эта форма обычно используется в численных библиотеках для получения срезов многомерных данных. В этом случае интерпретатор создаёт tuple из результатов выражений или срезов и передаёт этот кортеж специальному методу __getitem__() или __class_getitem__(), как и выше.

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

>>> demo['spam',]
обращение по индексатору: ('spam',)

6.3.2.3. Индексирование «со звёздочкой»

Добавлено в версии 3.11: Выражения в tuple_slices могут записываться со звёздочкой. См. PEP 646.

Индексатор может также содержать выражение со звёздочкой. В этом случае интерпретатор распаковывает результат в кортеж и передаёт этот кортеж в __getitem__() или __class_getitem__():

# продолжение с экземпляром SubscriptionDemo, определённым выше:
>>> demo[*range(10)]
обращение по индексатору: (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

Выражения со звёздочкой можно сочетать с выражениями и срезами, разделёнными запятыми:

>>> demo['а', 'б', *range(3), 'в']
обращение по индексатору: ('а', 'б', 0, 1, 2, 'в')

6.3.2.4. Формальная грамматика индексирования

subscription:     primary '[' subscript ']'
subscript:        single_subscript | tuple_subscript
single_subscript: proper_slice | assignment_expression
proper_slice:     [expression] ":" [expression] [ ":" [expression] ]
tuple_subscript:  ','.(single_subscript | starred_expression)+ [',']

Напомним, что оператор | обозначает упорядоченный выбор. В частности, в subscript, если подходят обе альтернативы, приоритет имеет первая (single_subscript).

6.3.3. Вызовы

Вызов запускает вызываемый объект (например, функцию), передавая ему, возможно, пустой набор аргументов:

call:                 primary "(" [argument_list [","] | comprehension] ")"
argument_list:        positional_arguments ["," starred_and_keywords]
                        ["," keywords_arguments]
                      | starred_and_keywords ["," keywords_arguments]
                      | keywords_arguments
positional_arguments: positional_item ("," positional_item)*
positional_item:      assignment_expression | "*" expression
starred_and_keywords: ("*" expression | keyword_item)
                      ("," "*" expression | "," keyword_item)*
keywords_arguments:   (keyword_item | "**" expression)
                      ("," keyword_item | "," "**" expression)*
keyword_item:         identifier "=" expression

После позиционных и именованных аргументов может стоять необязательная завершающая запятая, которая не влияет на семантику.

Первичное выражение должно вычисляться в вызываемый объект (вызываемыми являются пользовательские функции, встроенные функции, методы встроенных объектов, объекты классов, методы экземпляров классов и все объекты, имеющие метод __call__()). Все выражения аргументов вычисляются до попытки вызова. Синтаксис списков формальных параметров см. в разделе Определения функций.

Если есть именованные аргументы, они сначала преобразуются в позиционные следующим образом. Сначала для формальных параметров создаётся список незаполненных слотов. Если позиционных аргументов N, они помещаются в первые N слотов. Затем для каждого именованного аргумента по идентификатору определяется соответствующий слот (если идентификатор совпадает с именем первого формального параметра, используется первый слот, и так далее). Если слот уже заполнен, возбуждается исключение TypeError. В противном случае аргумент помещается в слот и заполняет его (даже если выражение равно None, оно заполняет слот). Когда все аргументы обработаны, слоты, оставшиеся незаполненными, заполняются соответствующими значениями по умолчанию из определения функции. (Значения по умолчанию вычисляются один раз, при определении функции; поэтому изменяемый объект, например список или словарь, используемый в качестве значения по умолчанию, будет общим для всех вызовов, в которых не указано значение аргумента для соответствующего слота; этого обычно следует избегать.) Если остались незаполненные слоты, для которых значение по умолчанию не задано, возбуждается исключение TypeError. В противном случае список заполненных слотов используется в качестве списка аргументов вызова.

Реализация может предоставлять встроенные функции, у позиционных параметров которых нет имён, даже если для целей документации они «названы», и которые поэтому нельзя передать как именованные аргументы. В CPython так обстоит дело с функциями, написанными на C, которые используют PyArg_ParseTuple() для разбора своих аргументов.

Если позиционных аргументов больше, чем слотов формальных параметров, возбуждается исключение TypeError, если только нет формального параметра, использующего синтаксис *identifier. В этом случае данный формальный параметр получает кортеж, содержащий лишние позиционные аргументы (или пустой кортеж, если лишних позиционных аргументов не было).

Если какой-либо именованный аргумент не соответствует имени формального параметра, возбуждается исключение TypeError, если только нет формального параметра, использующего синтаксис **identifier. В этом случае данный формальный параметр получает словарь, содержащий лишние именованные аргументы (ключами служат имена аргументов, а значениями — переданные значения), или (новый) пустой словарь, если лишних именованных аргументов не было.

Если в вызове функции встречается синтаксис *expression, то expression должно вычисляться в итерируемый объект. Элементы этих итерируемых объектов рассматриваются так, как если бы они были дополнительными позиционными аргументами. Для вызова f(x1, x2, *y, x3, x4), если y вычисляется в последовательность y1, …, yM, это будет эквивалентно вызову с M+4 позиционными аргументами x1, x2, y1, …, yM, x3, x4.

Следствием этого является то, что, хотя синтаксис *expression может стоять после явных именованных аргументов, он обрабатывается до именованных аргументов (и любых аргументов **expression — см. ниже). Так:

>>> def f(a, b):
...     print(a, b)
...
>>> f(b=1, *(2,))
2 1
>>> f(a=1, *(2,))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() got multiple values for keyword argument 'a'
>>> f(1, *(2,))
1 2

Редко случается, что в одном вызове используются и именованные аргументы, и синтаксис *expression, поэтому на практике такая путаница возникает нечасто.

Если в вызове функции встречается синтаксис **expression, то expression должно вычисляться в отображение, содержимое которого рассматривается как дополнительные именованные аргументы. Если параметр, соответствующий какому-либо ключу, уже получил значение (через явный именованный аргумент или из другой распаковки), возбуждается исключение TypeError.

Когда используется **expression, каждый ключ в этом отображении должен быть строкой. Каждое значение из отображения присваивается первому формальному параметру, допускающему передачу по имени, имя которого равно ключу. Ключ не обязан быть идентификатором Python (например, "max-temp °F" допустим, хотя и не совпадёт ни с одним формальным параметром, который можно объявить). Если ни один формальный параметр не подходит, пара «ключ — значение» собирается параметром **, если он есть, а если его нет, возбуждается исключение TypeError.

Формальные параметры, использующие синтаксис *identifier или **identifier, нельзя использовать как слоты для позиционных аргументов или как имена именованных аргументов.

Изменено в версии 3.5: Вызовы функций принимают любое число распаковок * и **, позиционные аргументы могут следовать за распаковками итерируемых объектов (*), а именованные аргументы — за распаковками словарей (**). Первоначально предложено в PEP 448.

Вызов всегда возвращает некоторое значение, возможно None, если только он не возбуждает исключение. Как это значение вычисляется, зависит от типа вызываемого объекта.

Если это —

пользовательская функция:

Выполняется блок кода функции, которому передаётся список аргументов. Первое, что сделает блок кода, — свяжет формальные параметры с аргументами; это описано в разделе Определения функций. Когда блок кода выполняет инструкцию return, она задаёт возвращаемое значение вызова функции. Если выполнение доходит до конца блока кода, не выполнив инструкцию return, возвращаемое значение равно None.

встроенная функция или метод:

Результат определяется интерпретатором; описания встроенных функций и методов см. в разделе Встроенные функции.

объект класса:

Возвращается новый экземпляр этого класса.

метод экземпляра класса:

Вызывается соответствующая пользовательская функция со списком аргументов, который на единицу длиннее списка аргументов вызова: экземпляр становится первым аргументом.

экземпляр класса:

Класс должен определять метод __call__(); тогда эффект такой же, как если бы был вызван этот метод.

6.4. Выражение await

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

await_expr: "await" primary

Добавлено в версии 3.5.

6.5. Оператор возведения в степень

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

power: (await_expr | primary) ["**" u_expr]

Таким образом, в последовательности степенных и унарных операторов без скобок операторы вычисляются справа налево (это не ограничивает порядок вычисления операндов): -1**2 даёт -1.

Оператор возведения в степень имеет ту же семантику, что и встроенная функция pow(), вызванная с двумя аргументами: он возвращает левый аргумент, возведённый в степень, равную правому аргументу. Числовые аргументы сначала приводятся к общему типу, и результат имеет этот тип.

Для операндов типа int результат имеет тот же тип, что и операнды, если только второй аргумент не отрицателен. В этом случае все аргументы преобразуются во float и возвращается результат типа float. Например, 10**2 возвращает 100, а 10**-2 возвращает 0.01.

Возведение 0.0 в отрицательную степень приводит к ZeroDivisionError. Возведение отрицательного числа в дробную степень даёт число типа complex. (В более ранних версиях возбуждалось ValueError.)

Эту операцию можно настроить с помощью специальных методов __pow__() и __rpow__().

6.6. Унарные арифметические и побитовые операции

Все унарные арифметические и побитовые операции имеют одинаковый приоритет:

u_expr: power | "-" u_expr | "+" u_expr | "~" u_expr

Унарный оператор - (минус) возвращает значение, противоположное своему числовому аргументу. Операцию можно переопределить с помощью специального метода __neg__().

Унарный оператор + (плюс) возвращает свой числовой аргумент без изменений. Операцию можно переопределить с помощью специального метода __pos__().

Унарный оператор ~ (инверсия) возвращает побитовую инверсию своего целочисленного аргумента. Побитовая инверсия x определяется как -(x+1). Оператор применим только к целым числам и к пользовательским объектам, переопределяющим специальный метод __invert__().

Во всех трёх случаях, если аргумент имеет неподходящий тип, возбуждается исключение TypeError.

6.7. Бинарные арифметические операции

Бинарные арифметические операции имеют привычные уровни приоритета. Обратите внимание, что некоторые из этих операций применимы и к нечисловым типам. Помимо оператора возведения в степень, есть только два уровня: один для мультипликативных операторов и один для аддитивных:

m_expr: u_expr | m_expr "*" u_expr | m_expr "@" m_expr |
        m_expr "//" u_expr | m_expr "/" u_expr |
        m_expr "%" u_expr
a_expr: m_expr | a_expr "+" m_expr | a_expr "-" m_expr

Оператор * (умножение) возвращает произведение своих аргументов. Аргументы должны быть либо оба числами, либо один из них должен быть целым числом, а другой — последовательностью. В первом случае числа приводятся к общему вещественному типу и затем перемножаются. Во втором случае выполняется повторение последовательности. При этом отрицательное число повторений даёт пустую последовательность.

Эту операцию можно настроить с помощью специальных методов __mul__() и __rmul__().

Изменено в версии 3.14: Если только один операнд является комплексным числом, другой операнд преобразуется в число с плавающей точкой.

Оператор @ (собака) предназначен для умножения матриц. Ни один встроенный тип Python не реализует этот оператор.

Эту операцию можно настроить с помощью специальных методов __matmul__() и __rmatmul__().

Добавлено в версии 3.5.

Операторы / (деление) и // (целочисленное деление) возвращают частное своих аргументов. Числовые аргументы сначала приводятся к общему типу. Деление целых чисел даёт float, а целочисленное деление целых чисел — целое число. Результат целочисленного деления вычисляется применением функции «округление вниз» к математическому частному. Деление на ноль возбуждает исключение ZeroDivisionError.

Операцию деления можно настроить с помощью специальных методов __truediv__() и __rtruediv__(). Операцию целочисленного деления можно настроить с помощью специальных методов __floordiv__() и __rfloordiv__().

Оператор % (остаток от деления) возвращает остаток от деления первого аргумента на второй. Числовые аргументы сначала приводятся к общему типу. Нулевой правый аргумент возбуждает исключение ZeroDivisionError. Аргументы могут быть числами с плавающей точкой, например, 3.14%0.7 равно 0.34 (поскольку 3.14 равно 4*0.7 + 0.34). Оператор взятия остатка от деления всегда возвращает результат с тем же знаком, что и у второго операнда (или ноль); абсолютное значение результата строго меньше абсолютного значения второго операнда [1].

Операторы целочисленного деления и взятия остатка от деления связаны следующим тождеством: x == (x//y)*y + (x%y). Целочисленное деление и взятия остатка от деления также связаны со встроенной функцией divmod(): divmod(x, y) == (x//y, x%y). [2].

Помимо выполнения операции взятия остатка над числами, оператор % также перегружен строковыми объектами для форматирования строк в старом стиле (оно же интерполяция). Синтаксис форматирования строк описан в справочнике по библиотеке Python, в разделе printf-style String Formatting.

Операцию остатка можно настроить с помощью специальных методов __mod__() и __rmod__().

Оператор целочисленного деления, оператор взятия остатка от деления и функция divmod() не определены для комплексных чисел. Вместо этого, если это уместно, преобразуйте такие числа в числа с плавающей точкой с помощью функции abs().

Оператор + (сложение) возвращает сумму своих аргументов. Аргументы должны быть либо оба числами, либо оба последовательностями одного типа. В первом случае числа приводятся к общему вещественному типу и затем складываются. Во втором случае последовательности конкатенируются.

Эту операцию можно настроить с помощью специальных методов __add__() и __radd__().

Изменено в версии 3.14: Если только один операнд является комплексным числом, другой операнд преобразуется в число с плавающей точкой.

Оператор - (вычитание) возвращает разность своих аргументов. Числовые аргументы сначала приводятся к общему вещественному типу.

Эту операцию можно настроить с помощью специальных методов __sub__() и __rsub__().

Изменено в версии 3.14: Если только один операнд является комплексным числом, другой операнд преобразуется в число с плавающей точкой.

6.8. Операции сдвига

Операции сдвига имеют более низкий приоритет, чем арифметические операции:

shift_expr: a_expr | shift_expr ("<<" | ">>") a_expr

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

Операцию сдвига влево можно настроить с помощью специальных методов __lshift__() и __rlshift__(). Операцию сдвига вправо можно настроить с помощью специальных методов __rshift__() и __rrshift__().

Сдвиг вправо на n битов определяется как целочисленное деление на pow(2,n). Сдвиг влево на n битов определяется как умножение на pow(2,n).

6.9. Бинарные побитовые операции

Каждая из трёх побитовых операций имеет свой уровень приоритета:

and_expr: shift_expr | and_expr "&" shift_expr
xor_expr: and_expr | xor_expr "^" and_expr
or_expr:  xor_expr | or_expr "|" xor_expr

Оператор & возвращает побитовое И своих аргументов, которые должны быть целыми числами, либо один из них должен быть пользовательским объектом, переопределяющим специальные методы __and__() или __rand__().

Оператор ^ возвращает побитовое XOR (исключающее ИЛИ) своих аргументов, которые должны быть целыми числами, либо один из них должен быть пользовательским объектом, переопределяющим специальные методы __xor__() или __rxor__().

Оператор | возвращает побитовое (включающее) ИЛИ своих аргументов, которые должны быть целыми числами, либо один из них должен быть пользовательским объектом, переопределяющим специальные методы __or__() или __ror__().

6.10. Сравнения

В отличие от C, все операции сравнения в Python имеют одинаковый приоритет, более низкий, чем у любых арифметических операций, операций сдвига и побитовых операций. Кроме того, в отличие от C, выражения вида a < b < c интерпретируются так, как принято в математике:

comparison:    or_expr (comp_operator or_expr)*
comp_operator: "<" | ">" | "==" | ">=" | "<=" | "!="
               | "is" ["not"] | ["not"] "in"

Сравнения возвращают логические значения: True или False. Пользовательские методы расширенного сравнения могут возвращать значения других типов. В этом случае в логическом контексте Python вызывает для такого значения bool().

Сравнения можно произвольно объединять в цепочки, например, x < y <= z эквивалентно x < y and y <= z, за исключением того, что y вычисляется только один раз (но в обоих случаях z вообще не вычисляется, если обнаружено, что x < y ложно).

Формально, если a, b, c, …, y, z — выражения, а op1, op2, …, opN — операторы сравнения, то a op1 b op2 c ... y opN z эквивалентно a op1 b and b op2 c and ... y opN z, за исключением того, что каждое выражение вычисляется не более одного раза.

Обратите внимание, что a op1 b op2 c не подразумевает никакого сравнения между a и c, так что, например, x < y > z вполне допустимо (хотя, возможно, и некрасиво).

6.10.1. Сравнение значений

Операторы <, >, ==, >=, <= и != сравнивают значения двух объектов. Объекты не обязаны иметь один и тот же тип.

В главе Объекты, значения и типы данных говорится, что у объектов есть значение (помимо типа и идентификатора). Значение объекта — довольно абстрактное понятие в Python: например, не существует канонического метода доступа к значению объекта. Кроме того, нет требования, чтобы значение объекта строилось каким-то определённым образом, например, состояло из всех его атрибутов данных. Операторы сравнения реализуют определённое представление о том, что такое значение объекта. Можно считать, что они определяют значение объекта косвенно, через свою реализацию сравнения.

Поскольку все типы являются (прямыми или косвенными) подтипами object, они наследуют от object поведение сравнения по умолчанию. Типы могут настроить своё поведение при сравнении, реализовав методы расширенного сравнения, такие как __lt__(), описанные в разделе Базовая настройка поведения.

Поведение по умолчанию при сравнении на равенство (== и !=) основано на идентификаторах объектов. Следовательно, сравнение на равенство экземпляров с одинаковыми идентификаторами даёт равенство, а сравнение на равенство экземпляров с разными идентификаторами даёт неравенство. Мотивация такого поведения по умолчанию — желание, чтобы все объекты были рефлексивными (т. е. из x is y следовало x == y).

По умолчанию упорядочивающие сравнения (<, >, <= и >=) не поддерживаются: попытка выполнить такое сравнение возбуждает TypeError. Причина такого поведения — отсутствие инварианта, аналогичного тому, что есть для равенства.

Поведение сравнения на равенство по умолчанию, при котором экземпляры с разными идентификаторами всегда неравны, может расходиться с потребностями типов, у которых есть разумное определение значения объекта и равенства, основанного на значении. Таким типам необходимо настраивать своё поведение при сравнении, и некоторые встроенные типы так и делают.

Следующий список описывает поведение при сравнении наиболее важных встроенных типов.

  • Числа встроенных числовых типов (Numeric Types — int, float, complex) и типов стандартной библиотеки fractions.Fraction и decimal.Decimal можно сравнивать как внутри своих типов, так и между ними, с тем ограничением, что комплексные числа не поддерживают упорядочивающие сравнения. В пределах возможностей задействованных типов они сравниваются математически (алгоритмически) правильно, без потери точности.

    Значения «не число» float('NaN') и decimal.Decimal('NaN') особые. Любое упорядочивающее сравнение числа со значением «не число» ложно. Нелогичное на первый взгляд следствие — значения «не число» не равны сами себе. Например, если x = float('NaN'), то 3 < x, x < 3 и x == x ложны, а x != x истинно. Такое поведение соответствует IEEE 754.

  • None и NotImplemented — синглтоны. В PEP 8 рекомендуется всегда сравнивать синглтоны с помощью is или is not, а не операторов равенства.

  • Двоичные последовательности (экземпляры bytes или bytearray) можно сравнивать как внутри своих типов, так и между ними. Они сравниваются лексикографически по числовым значениям своих элементов.

  • Строки (экземпляры str) сравниваются лексикографически по числовым кодовым позициям Юникода своих символов (результату встроенной функции ord()). [3]

    Строки и двоичные последовательности нельзя сравнивать напрямую.

  • Последовательности (экземпляры tuple, list или range) можно сравнивать только внутри каждого из своих типов, причём объекты range не поддерживают упорядочивающие сравнения. Сравнение на равенство между этими типами даёт неравенство, а упорядочивающее сравнение между этими типами возбуждает TypeError.

    Последовательности сравниваются лексикографически с помощью сравнения соответствующих элементов. Встроенные контейнеры, как правило, считают, что идентичные объекты равны самим себе. Это позволяет им пропускать проверки на равенство для идентичных объектов, чтобы повысить производительность и сохранить свои внутренние инварианты.

    Лексикографическое сравнение встроенных коллекций работает следующим образом:

    • Чтобы две коллекции были равны, они должны быть одного типа, иметь одинаковую длину, а каждая пара соответствующих элементов должна быть равна (например, [1,2] == (1,2) ложно, потому что типы различны).

    • Коллекции, поддерживающие упорядочивающие сравнения, упорядочиваются так же, как их первые неравные элементы (например, [1,2,x] <= [1,2,y] имеет то же значение, что и x <= y). Если соответствующего элемента не существует, первой упорядочивается более короткая коллекция (например, [1,2] < [1,2,3] истинно).

  • Отображения (экземпляры dict) равны тогда и только тогда, когда у них равные пары (key, value). Сравнение на равенство ключей и значений обеспечивает рефлексивность.

    Упорядочивающие сравнения (<, >, <= и >=) возбуждают TypeError.

  • Множества (экземпляры set или frozenset) можно сравнивать как внутри своих типов, так и между ними.

    Для них операторы упорядочивающего сравнения определены как проверки на подмножество и надмножество. Эти отношения не определяют полный порядок (например, множества {1,2} и {2,3} не равны, и ни одно из них не является подмножеством или надмножеством другого). Соответственно, множества не подходят в качестве аргументов функций, которые зависят от полного порядка (например, min(), max() и sorted() дают неопределённые результаты, если на вход подан список множеств).

    Сравнение множеств обеспечивает рефлексивность их элементов.

  • У большинства других встроенных типов методы сравнения не реализованы, поэтому они наследуют поведение сравнения по умолчанию.

Пользовательские классы, настраивающие своё поведение при сравнении, по возможности должны следовать некоторым правилам согласованности:

  • Сравнение на равенство должно быть рефлексивным. Другими словами, идентичные объекты должны быть равны:

    из x is y следует x == y

  • Сравнение должно быть симметричным. Другими словами, следующие выражения должны давать один и тот же результат:

    x == y и y == x

    x != y и y != x

    x < y и y > x

    x <= y и y >= x

  • Сравнение должно быть транзитивным. Это иллюстрируют следующие (неисчерпывающие) примеры:

    из x > y and y > z следует x > z

    из x < y and y <= z следует x < z

  • Обратное сравнение должно давать логическое отрицание. Другими словами, следующие выражения должны давать один и тот же результат:

    x == y и not x != y

    x < y и not x >= y (для полного порядка)

    x > y и not x <= y (для полного порядка)

    Последние два выражения применимы к коллекциям с полным порядком (например, к последовательностям, но не к множествам и не к отображениям). См. также декоратор @total_ordering.

  • Результат hash() должен быть согласован с равенством. Равные объекты должны либо иметь одинаковое хеш-значение, либо быть помечены как нехешируемые.

Python не принуждает к соблюдению этих правил согласованности. На самом деле значения «не число» — пример того, что эти правила не соблюдаются.

6.10.2. Операции проверки принадлежности

Операторы in и not in проверяют принадлежность. x in s вычисляется в True, если x является элементом s, и в False в противном случае. x not in s возвращает отрицание x in s. Это поддерживают все встроенные последовательности и типы множеств, а также словари, для которых in проверяет, есть ли в словаре заданный ключ. Для контейнерных типов, таких как list, tuple, set, frozenset, dict или collections.deque, выражение x in y эквивалентно any(x is e or x == e for e in y).

Для строковых и байтовых типов x in y равно True тогда и только тогда, когда x является подстрокой y. Эквивалентная проверка — y.find(x) != -1. Пустая строка всегда считается подстрокой любой другой строки, поэтому "" in "abc" вернёт True.

Для пользовательских классов, определяющих метод __contains__(), x in y возвращает True, если y.__contains__(x) возвращает истинное значение, и False в противном случае.

Для пользовательских классов, которые не определяют __contains__(), но определяют __iter__(), x in y равно True, если при итерации по y порождается некоторое значение z, для которого выражение x is z or x == z истинно. Если во время итерации возбуждается исключение, это равносильно тому, что исключение возбудил in.

Наконец, пробуется старый протокол итерации: если класс определяет __getitem__(), x in y равно True тогда и только тогда, когда существует неотрицательный целочисленный индекс i, для которого x is y[i] or x == y[i], и ни один меньший целочисленный индекс не возбуждает исключение IndexError. (Если возбуждается любое другое исключение, это равносильно тому, что исключение возбудил in).

Оператор not in определён так, чтобы его значение истинности было обратным значению in.

6.10.3. Сравнение идентичности

Операторы is и is not проверяют идентификаторы объектов: x is y истинно тогда и только тогда, когда x и y — один и тот же объект. Идентификатор объекта определяется с помощью функции id(). x is not y даёт обратное значение истинности. [4]

6.11. Логические операции

or_test:  and_test | or_test "or" and_test
and_test: not_test | and_test "and" not_test
not_test: comparison | "not" not_test

В контексте логических операций, а также когда выражения используются в инструкциях управления потоком выполнения, следующие значения интерпретируются как ложные: False, None, числовой нуль всех типов, а также пустые строки и контейнеры (включая строки, кортежи, списки, словари, множества и frozenset). Все остальные значения интерпретируются как истинные. Пользовательские объекты могут настроить своё значение истинности, предоставив метод __bool__().

Оператор not возвращает True, если его аргумент ложен, и False в противном случае.

Выражение x and y сначала вычисляет x. Если x ложно, возвращается его значение, в противном случае вычисляется y и возвращается полученное значение.

Выражение x or y сначала вычисляет x. Если x истинно, возвращается его значение, в противном случае вычисляется y и возвращается полученное значение.

Обратите внимание, что ни and, ни or не ограничивают возвращаемое значение и его тип значениями False и True, а возвращают последний вычисленный аргумент. Иногда это полезно: например, если s — строка, которую нужно заменить значением по умолчанию, когда она пуста, то выражение s or 'foo' даёт нужное значение. Поскольку not должен создать новое значение, он возвращает логическое значение независимо от типа своего аргумента (например, not 'foo' даёт False, а не ''.)

6.12. Выражения присваивания

assignment_expression: [identifier ":="] expression

Выражение присваивания (иногда его также называют «именованным выражением» или «моржом») присваивает значение expression идентификатору identifier и одновременно возвращает значение expression.

Один из распространённых случаев применения — обработка найденных совпадений регулярных выражений:

if matching := pattern.search(data):
    do_something(matching)

Или обработка файлового потока по частям:

while chunk := file.read(9000):
    process(chunk)

Выражения присваивания должны быть заключены в круглые скобки, если они используются как инструкции-выражения или как подвыражения в срезах, условных выражениях, лямбдах, именованных аргументов и условиях во включениях, а также в инструкциях assert, with и assignment. Во всех остальных местах, где их можно использовать, скобки не требуются, в том числе в инструкциях if и while.

Добавлено в версии 3.8: Подробнее о выражениях присваивания см. в PEP 572.

6.13. Условные выражения

conditional_expression: or_test ["if" or_test "else" expression]
expression:             conditional_expression | lambda_expr

Условное выражение (иногда его называют «тернарным оператором») — это альтернатива инструкции if-else. Поскольку это выражение, оно возвращает значение и может использоваться как подвыражение.

Выражение x if C else y сначала вычисляет условие C, а не x. Если C истинно, вычисляется x и возвращается его значение, в противном случае вычисляется y и возвращается его значение.

Подробнее об условных выражениях см. в PEP 308.

6.14. Лямбды

lambda_expr: "lambda" [parameter_list] ":" expression

Лямбда-выражения (иногда их называют лямбда-формами) используются для создания анонимных функций. Выражение lambda parameters: expression возвращает объект функции. Этот безымянный объект ведёт себя как объект функции, определённый так:

def <lambda>(parameters):
    return expression

Синтаксис списков параметров см. в разделе Определения функций. Обратите внимание, что функции, созданные с помощью лямбда-выражений, не могут содержать инструкции и аннотации.

6.15. Списки выражений

starred_expression:       "*" or_expr | expression
flexible_expression:      assignment_expression | starred_expression
flexible_expression_list: flexible_expression ("," flexible_expression)* [","]
starred_expression_list:  starred_expression ("," starred_expression)* [","]
expression_list:          expression ("," expression)* [","]
yield_list:               expression_list | starred_expression "," [starred_expression_list]

Если список выражений не является частью явного представления списка или множества, то список, содержащий хотя бы одну запятую, даёт кортеж. Длина кортежа равна числу выражений в списке. Выражения вычисляются слева направо.

Завершающая запятая нужна только для создания кортежа из одного элемента, например 1,, а во всех остальных случаях она необязательна. Одиночное выражение без завершающей запятой не создаёт кортеж, а даёт значение этого выражения. (Чтобы создать пустой кортеж, используйте пустую пару круглых скобок: ().)

6.15.1. Распаковка итерируемых объектов

В списке выражений или в явном представлении кортежа, списка или множества перед любым выражением можно поставить звёздочку (*). Это обозначает распаковку итерируемого объекта.

Во время выполнения выражение со звёздочкой должно вычисляться в итерируемый объект. Этот объект разворачивается в последовательность элементов, которые включаются в новый кортеж, список или множество на месте распаковки.

Добавлено в версии 3.5: Первоначально распаковка итерируемых объектов в списках выражений предложена в PEP 448.

Добавлено в версии 3.11: Любой элемент списка выражений может быть помечен звёздочкой. См. PEP 646.

6.16. Порядок вычислений

Python вычисляет выражения слева направо. Обратите внимание, что при вычислении присваивания правая часть вычисляется раньше левой.

В следующих строках выражения вычисляются в порядке возрастания их числовых суффиксов:

expr1, expr2, expr3, expr4
(expr1, expr2, expr3, expr4)
{expr1: expr2, expr3: expr4}
expr1 + expr2 * (expr3 - expr4)
expr1(expr2, expr3, *expr4, **expr5)
expr3, expr4 = expr1, expr2

6.17. Приоритет операторов

В следующей таблице приведены приоритеты операторов в Python: от наивысшего (операторы, связывающие сильнее всего) до низшего (операторы, связывающие слабее всего). Операторы в одной строке таблицы имеют одинаковый приоритет. Если синтаксис не указан явно, операторы бинарные. Операторы в одной строке группируются слева направо (кроме возведения в степень и условных выражений, которые группируются справа налево).

Обратите внимание, что сравнения, проверки принадлежности и проверки идентичности имеют одинаковый приоритет и допускают объединение в цепочки слева направо, как описано в разделе Сравнения.

Оператор

Описание

(expressions...),

[expressions...], {key: value...}, {expressions...}

Связывание или выражение в скобках, явное представление списка, явное представление словаря, явное представление множества

x[index], x[index:index] x(arguments...), x.attribute

Индексирование (включая срезы), вызов, обращение к атрибуту

await x

Выражение await

**

Возведение в степень [5]

+x, -x, ~x

Плюс, минус, побитовое НЕ

*, @, /, //, %

Умножение, матричное умножение, деление, целочисленное деление, остаток [6]

+, -

Сложение и вычитание

<<, >>

Сдвиги

&

Побитовое И

^

Побитовое XOR

|

Побитовое ИЛИ

in, not in, is, is not, <, <=, >, >=, !=, ==

Сравнения, включая проверки принадлежности и проверки идентичности

not x

Логическое НЕ

and

Логическое И

or

Логическое ИЛИ

if – else

Условное выражение

lambda

Лямбда-выражение

:=

Выражение присваивания

Примечания