6. Выражения

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

Примечания по синтаксису: В этой и следующих главах для описания синтаксиса, а не лексического анализа, будет использоваться расширенная нотация BNF. Когда (одна из альтернатив) синтаксического правила имеет вид

name ::=  othername

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

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

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

  • Если один из аргументов является комплексным числом, второй преобразуется в комплексный;

  • в противном случае, если один из аргументов является числом с плавающей точкой, второй аргумент преобразуется в число с плавающей точкой;

  • в противном случае оба должны быть целыми числами, и преобразование не требуется.

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

6.2. Атомы

Атомы - это самые основные элементы выражений. Простейшими атомами являются идентификаторы или литералы. Формы, заключенные в круглые скобки, скобки или брекеты, также синтаксически классифицируются как атомы. Синтаксис для атомов следующий:

atom      ::=  identifier | literal | enclosure
enclosure ::=  parenth_form | list_display | dict_display | set_display
               | generator_expression | yield_atom

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

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

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

Искажение частных имен: Если идентификатор, который текстуально встречается в определении класса, начинается с двух или более символов подчеркивания и не заканчивается двумя или более символами подчеркивания, он считается private name этого класса. Частные имена преобразуются в более длинную форму перед тем, как для них генерируется код. Преобразование вставляет перед именем имя класса, удаляя ведущие подчеркивания и вставляя одно подчеркивание. Например, идентификатор __spam, встречающийся в классе с именем Ham, будет преобразован в _Ham__spam. Это преобразование не зависит от синтаксического контекста, в котором используется идентификатор. Если преобразованное имя очень длинное (более 255 символов), может произойти усечение, определенное реализацией. Если имя класса состоит только из символов подчеркивания, преобразование не выполняется.

6.2.2. Литература

Python поддерживает строковые и байтовые литералы, а также различные числовые литералы:

literal ::=  stringliteral | bytesliteral
             | integer | floatnumber | imagnumber

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

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

6.2.3. Парентезные формы

Форма с круглыми скобками - это список необязательных выражений, заключенный в круглые скобки:

parenth_form ::=  "(" [starred_expression] ")"

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

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

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

6.2.4. Дисплеи для списков, наборов и словарей

Для построения списка, набора или словаря Python предоставляет специальный синтаксис, называемый «отображениями», каждый из которых имеет две разновидности:

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

  • Они вычисляются с помощью набора циклических и фильтрующих инструкций, называемых comprehension.

Общими элементами синтаксиса для постижений являются:

comprehension ::=  assignment_expression comp_for
comp_for      ::=  ["async"] "for" target_list "in" or_test [comp_iter]
comp_iter     ::=  comp_for | comp_if
comp_if       ::=  "if" or_test [comp_iter]

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

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

Итерируемое выражение в самом левом предложении for оценивается непосредственно в объемлющей области и затем передается в качестве аргумента в неявно вложенную область. Последующие предложения for и любое условие фильтрации в самом левом предложении for не могут быть оценены в объемлющей области, поскольку они могут зависеть от значений, полученных из самого левого итерируемого выражения. Например: [x*y for x in range(10) for y in range(x, x+10)].

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

Начиная с Python 3.6, в функции async def предложение async for может использоваться для итерации по asynchronous iterator. Понимание в функции async def может состоять из предложения for или async for, следующего за ведущим выражением, может содержать дополнительные предложения for или async for, а также использовать выражения await. Если постижение содержит либо async for клаузул, либо await выражений, либо другие асинхронные постижения, оно называется asynchronous comprehension. Асинхронное постижение может приостановить выполнение функции coroutine, в которой оно появляется. См. также PEP 530.

Added in version 3.6: Были введены асинхронные постижения.

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

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

6.2.5. Отображение списка

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

list_display ::=  "[" [starred_list | comprehension] "]"

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

6.2.6. Установите дисплеи

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

set_display ::=  "{" (starred_list | comprehension) "}"

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

Пустое множество не может быть построено с помощью {}; этот литерал строит пустой словарь.

6.2.7. Словарные дисплеи

Отображение словаря - это возможно пустая серия элементов dict (пар ключ/значение), заключенных в фигурные скобки:

dict_display       ::=  "{" [dict_item_list | dict_comprehension] "}"
dict_item_list     ::=  dict_item ("," dict_item)* [","]
dict_item          ::=  expression ":" expression | "**" or_expr
dict_comprehension ::=  expression ":" expression comp_for

При отображении словаря создается новый объект словаря.

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

Двойная звездочка ** обозначает dictionary unpacking. Ее операнд должен быть mapping. Каждый элемент отображения добавляется в новый словарь. Более поздние значения заменяют значения, уже установленные предыдущими элементами dict и предыдущими распаковками словаря.

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

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

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

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

6.2.8. Генератор выражений

Выражение генератора - это компактное обозначение генератора в круглых скобках:

generator_expression ::=  "(" expression comp_for ")"

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

Переменные, используемые в выражении генератора, лениво оцениваются при вызове метода __next__() для объекта генератора (так же, как и в обычных генераторах). Однако итерируемое выражение в самом левом предложении for оценивается немедленно, так что ошибка, вызванная им, будет выдана в момент определения выражения генератора, а не в момент получения первого значения. Последующие предложения for и любое условие фильтрации в самом левом предложении for не могут быть оценены в объемлющей области, поскольку они могут зависеть от значений, полученных из самой левой итерируемой переменной. Например: (x*y for x in range(10) for y in range(x, x+10)).

Скобки могут быть опущены в вызовах с одним аргументом. Подробности см. в разделе Звонки.

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

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

Added in version 3.6: Появились асинхронные выражения-генераторы.

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

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

6.2.9. Выражения доходности

yield_atom       ::=  "(" yield_expression ")"
yield_from       ::=  "yield" "from" expression
yield_expression ::=  "yield" expression_list | yield_from

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

def gen():  # defines a generator function
    yield 123

async def agen(): # defines an asynchronous generator function
    yield 123

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

Изменено в версии 3.8: Выражения Yield запрещены в неявно вложенных диапазонах, используемых для реализации осмысления и генераторных выражений.

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

Когда вызывается функция-генератор, она возвращает итератор, называемый генератором. Затем этот генератор управляет выполнением функции-генератора. Выполнение начинается, когда вызывается один из методов генератора. В это время выполнение переходит к первому выражению yield, где оно снова приостанавливается, возвращая вызывающему генератору значение expression_list или None, если expression_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 - Простые генераторы

Предложение по добавлению генераторов и оператора yield в Python.

PEP 342 - Корутины через расширенные генераторы

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

PEP 380 - Синтаксис для делегирования полномочий подгенератору

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

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

Предложение, расширяющее PEP 492 за счет добавления возможностей генератора в функции coroutine.

6.2.9.1. Методы генератора-итератора

В этом подразделе описаны методы итератора генератора. Их можно использовать для управления выполнением функции-генератора.

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

generator.__next__()

Запускает выполнение функции-генератора или возобновляет его на последнем выполненном выражении yield. Когда генераторная функция возобновляется с помощью метода __next__(), текущее выражение yield всегда оценивается в None. Затем выполнение продолжается до следующего выражения yield, где генератор снова приостанавливается, и значение expression_list возвращается вызывающему __next__(). Если генератор завершается, не выдав другого значения, поднимается исключение StopIteration.

Обычно этот метод вызывается неявно, например, циклом for или встроенной функцией next().

generator.send(value)

Возобновляет выполнение и «отправляет» значение в функцию-генератор. Аргумент value становится результатом текущего выражения yield. Метод send() возвращает следующее значение, выданное генератором, или поднимает значение StopIteration, если генератор завершается, не выдав другого значения. Когда для запуска генератора вызывается send(), он должен быть вызван с None в качестве аргумента, поскольку нет выражения yield, которое могло бы получить значение.

generator.throw(value)
generator.throw(type[, value[, traceback]])

Вызывает исключение в точке, где генератор был приостановлен, и возвращает следующее значение, выданное функцией генератора. Если генератор завершается, не выдав другого значения, вызывается исключение StopIteration. Если функция-генератор не перехватывает переданное исключение или вызывает другое исключение, то оно передается вызывающей стороне.

При обычном использовании это вызывается с одним экземпляром исключения, подобно тому, как используется ключевое слово raise.

Однако для обратной совместимости поддерживается вторая сигнатура, которая перешла из старых версий Python. Аргумент type должен быть классом исключения, а value - экземпляром исключения. Если значение не предоставлено, вызывается конструктор type для получения экземпляра. Если указан traceback, то он устанавливается для исключения, иначе любой существующий атрибут __traceback__, хранящийся в value, может быть очищен.

Изменено в версии 3.12: Вторая сигнатура (type[, value[, traceback]]]) устарела и может быть удалена в будущей версии Python.

generator.close()

Поднимает GeneratorExit в точке, где функция-генератор была приостановлена. Если функция-генератор перехватывает исключение и возвращает значение, то это значение возвращается из close(). Если функция-генератор уже закрыта или вызвала GeneratorExit (не поймав исключение), close() возвращает None. Если генератор выдает значение, вызывается RuntimeError. Если генератор вызывает любое другое исключение, оно передается вызывающей стороне. Если генератор уже завершился из-за исключения или обычного выхода, close() возвращает None и не имеет других последствий.

Изменено в версии 3.13: Если генератор возвращает значение после закрытия, то это значение возвращается через close().

6.2.9.2. Примеры

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

>>> def echo(value=None):
...     print("Execution starts when 'next()' is called for the first time.")
...     try:
...         while True:
...             try:
...                 value = (yield value)
...             except Exception as e:
...                 value = e
...     finally:
...         print("Don't forget to clean up when 'close()' is called.")
...
>>> generator = echo(1)
>>> print(next(generator))
Execution starts when 'next()' is called for the first time.
1
>>> print(next(generator))
None
>>> print(generator.send(2))
2
>>> generator.throw(TypeError, "spam")
TypeError('spam',)
>>> generator.close()
Don't forget to clean up when 'close()' is called.

Примеры использования yield from смотрите в разделе PEP 380: Синтаксис для делегирования полномочий субгенератору в «Что нового в Python».

6.2.9.3. Функции асинхронного генератора

Наличие выражения yield в функции или методе, заданном с помощью async def, дополнительно определяет функцию как функцию asynchronous generator.

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

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

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

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

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

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

6.2.9.4. Асинхронные методы генератора-итератора

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

coroutine agen.__anext__()

Возвращает awaitable, который при запуске начинает выполнение асинхронного генератора или возобновляет его на последнем выполненном выражении yield. Когда функция асинхронного генератора возобновляется с помощью метода __anext__(), текущее выражение yield всегда оценивается в None в возвращаемом awaitable, который при запуске переходит к следующему выражению yield. Значение expression_list выражения yield - это значение StopIteration исключения, поднятого завершающей корутиной. Если асинхронный генератор завершается, не выдав другого значения, то вместо этого awaitable поднимает исключение StopAsyncIteration, сигнализируя о завершении асинхронной итерации.

Обычно этот метод неявно вызывается циклом async for.

coroutine agen.asend(value)

Возвращает awaitable, который при выполнении возобновляет выполнение асинхронного генератора. Как и метод send() для генератора, этот метод «посылает» значение в функцию асинхронного генератора, и аргумент значение становится результатом текущего выражения yield. Функция awaitable, возвращаемая методом asend(), возвращает следующее значение, выданное генератором, в качестве значения поднятого StopIteration, или поднимает StopAsyncIteration, если асинхронный генератор завершается, не выдав другого значения. Когда asend() вызывается для запуска асинхронного генератора, он должен быть вызван с None в качестве аргумента, потому что не существует выражения yield, которое могло бы получить это значение.

coroutine agen.athrow(value)
coroutine agen.athrow(type[, value[, traceback]])

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

Изменено в версии 3.12: Вторая сигнатура (type[, value[, traceback]]]) устарела и может быть удалена в будущей версии Python.

coroutine agen.aclose()

Возвращает awaitable, который при выполнении выбросит GeneratorExit в функцию асинхронного генератора в точке, где она была приостановлена. Если после этого функция асинхронного генератора выйдет из себя, будет уже закрыта или вызовет исключение GeneratorExit (не поймав исключение), то возвращенный awaitable вызовет исключение StopIteration. Все последующие awaitable, возвращаемые при последующих вызовах асинхронного генератора, будут вызывать исключение StopAsyncIteration. Если асинхронный генератор выдает значение, то awaitable вызывает исключение RuntimeError. Если асинхронный генератор вызывает любое другое исключение, оно передается вызывающему awaitable. Если асинхронный генератор уже завершился из-за исключения или обычного выхода, то дальнейшие вызовы aclose() будут возвращать awaitable, который ничего не делает.

6.3. Праймериз

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

primary ::=  atom | attributeref | subscription | slicing | call

6.3.1. Ссылки на атрибуты

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

attributeref ::=  primary "." identifier

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

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

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

6.3.2. Подписки

Подписка на экземпляр container class обычно выбирает элемент из контейнера. Подписка на экземпляр generic class обычно возвращает объект GenericAlias.

subscription ::=  primary "[" expression_list "]"

Когда объект подписан, интерпретатор оценивает основной объект и список выражений.

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

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

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

  1. Сопоставления. Если первичным является mapping, список выражений должен привести к объекту, значение которого является одним из ключей отображения, и подписка выбирает значение в отображении, соответствующее этому ключу. Примером встроенного класса отображения является класс dict.

  2. Последовательности. Если первичным является sequence, список выражений должен быть оценен как int или slice (как обсуждается в следующем разделе). Примерами встроенных классов последовательностей являются классы str, list и tuple.

Формальный синтаксис не предусматривает специальных условий для отрицательных индексов в sequences. Однако все встроенные последовательности предоставляют метод __getitem__(), который интерпретирует отрицательные индексы путем добавления длины последовательности к индексу, так что, например, x[-1] выбирает последний элемент x. Полученное значение должно быть неотрицательным целым числом, меньшим, чем количество элементов в последовательности, и подписка выбирает элемент, индекс которого равен этому значению (считая от нуля). Поскольку поддержка отрицательных индексов и нарезки осуществляется в методе __getitem__() объекта, подклассы, переопределяющие этот метод, должны будут явно добавить эту поддержку.

Последовательность string - это особый вид последовательности, элементами которой являются символы. Символ - это не отдельный тип данных, а строка, состоящая ровно из одного символа.

6.3.3. Нарезка

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

slicing      ::=  primary "[" slice_list "]"
slice_list   ::=  slice_item ("," slice_item)* [","]
slice_item   ::=  expression | proper_slice
proper_slice ::=  [lower_bound] ":" [upper_bound] [ ":" [stride] ]
lower_bound  ::=  expression
upper_bound  ::=  expression
stride       ::=  expression

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

Семантика срезов выглядит следующим образом. Первичная часть индексируется (с помощью того же метода __getitem__(), что и обычная подписка) с ключом, который строится из списка срезов следующим образом. Если список срезов содержит хотя бы одну запятую, то ключом является кортеж, содержащий преобразования элементов срезов; в противном случае ключом является преобразование единственного элемента среза. Преобразованием элемента среза, который является выражением, является это выражение. Преобразованием правильного среза является объект slice (см. раздел Стандартная иерархия типов), атрибутами которого start, stop и step являются значения выражений, заданных как lower bound, upper bound и stride, соответственно, с заменой None для отсутствующих выражений.

6.3.4. Звонки

Вызов вызывает вызываемый объект (например, function) с возможной пустой серией arguments:

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__()). Все выражения аргументов оцениваются перед попыткой вызова. Синтаксис формальных списков parameter см. в разделе Определения функций.

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

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

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

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

Если в вызове функции встречается синтаксис *expression, то expression должен быть оценен как iterable. Элементы из этих итераций рассматриваются так, как если бы они были дополнительными позиционными аргументами. Для вызова 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 должен преобразовываться в mapping, содержимое которого рассматривается как дополнительный аргумент ключевого слова. Если параметру, соответствующему ключу, уже было присвоено значение (явным аргументом ключевого слова или в результате другой распаковки), возникает исключение TypeError.

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

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

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

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

Если это так…

функция, определяемая пользователем:

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

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

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

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

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

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

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

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

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

6.4. Ожидайте выражения

Приостанавливает выполнение coroutine на объекте awaitable. Может использоваться только внутри coroutine function.

await_expr ::=  "await" primary

Added in version 3.5.

6.5. Оператор питания

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

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

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

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

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

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

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

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

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

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

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

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

Унарный оператор ~ (invert) дает побитовую инверсию своего целочисленного аргумента. Побитовая инверсия 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__().

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

Added in version 3.5.

Операторы / (деление) и // (деление с полом) дают кутент своих аргументов. Числовые аргументы сначала преобразуются к общему типу. Деление целых чисел дает float, а поэтажное деление целых чисел - целое число; в результате получается математическое деление с применением функции „floor“ к результату. Деление на ноль вызывает исключение ZeroDivisionError.

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

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

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

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

Операция modulo может быть настроена с помощью специального метода __mod__().

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

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

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

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

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

6.8. Сменные операции

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

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

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

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

Сдвиг вправо на 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 своих аргументов, которые должны быть целыми числами или один из них должен быть пользовательским объектом, переопределяющим специальные методы __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. Пользовательские rich comparison methods могут возвращать небулевые значения. В этом случае 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. Типы могут настраивать свое поведение сравнения, реализуя rich comparison methods подобно __lt__(), описанному в Базовая настройка.

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

Сравнение порядка по умолчанию (<, >, <= и >=) не предусмотрено; попытка приводит к появлению TypeError. Мотивацией для такого поведения по умолчанию является отсутствие аналогичного инварианта, как для равенства.

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

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

  • Числа встроенных числовых типов (Числовые типы — 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) сравниваются лексикографически по числовым кодовым точкам Unicode (результат работы встроенной функции ord()) своих символов. [3]

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

  • Последовательности (экземпляры tuple, list или 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 не соблюдает эти правила согласованности. Фактически, значения not-a-number являются примером несоблюдения этих правил.

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).

Для типов string и bytes 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: False, None, числовой ноль всех типов, а также пустые строки и контейнеры (включая строки, кортежи, списки, словари, множества и замороженные множества). Все остальные значения интерпретируются как true. Определяемые пользователем объекты могут настраивать свое значение истинности, предоставляя метод __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)

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

Added in version 3.8: Более подробную информацию о выражениях присваивания см. в разделе PEP 572.

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

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

Условные выражения (иногда их называют «тернарным оператором») имеют самый низкий приоритет среди всех операций Python.

Выражение 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. Списки выражений

expression_list    ::=  expression ("," expression)* [","]
starred_list       ::=  starred_item ("," starred_item)* [","]
starred_expression ::=  expression | (starred_item ",")* [starred_item]
starred_item       ::=  assignment_expression | "*" or_expr

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

Звездочка * обозначает iterable unpacking. Ее операнд должен быть iterable. В месте распаковки итерируемое число разворачивается в последовательность элементов, которые включаются в новый кортеж, список или множество.

Added in version 3.5: Распаковка итераций в списках выражений, первоначально предложенная PEP 448.

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

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

Ожидайте выражения

**

Экспонирование [5]

+x, -x, ~x

Положительные, отрицательные, побитовые НЕ

*, @, /, //, %

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

+, -

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

<<, >>

Смены

&

Побитовое И

^

Побитовый XOR

|

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

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

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

not x

Булево НЕ

and

Булево И

or

Булево ИЛИ

ifelse

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

lambda

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

:=

Выражение назначения

Сноски