expressions.md
1> **Источник:** https://python-all.ru/3.7/reference/expressions.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 6. Выражения89В этой главе объясняется значение элементов выражений в Python.1011**Примечания к синтаксису:** В этой и следующих главах для описания синтаксиса, а не лексического анализа, будет использоваться расширенная нотация БНФ. Когда (одна из альтернатив) синтаксического правила имеет вид1213```1415name ::= othername16```1718и семантика не указана, то семантика этой формы `name` такая же, как для `othername`.1920## 6.1. Арифметические преобразования2122Когда в описании арифметического оператора ниже используется фраза «числовые аргументы преобразуются к общему типу», это означает, что реализация оператора для встроенных типов работает следующим образом:2324- Если хотя бы один аргумент – комплексное число, другой преобразуется в комплексное;25- в противном случае, если хотя бы один аргумент является числом с плавающей запятой, другой преобразуется в число с плавающей запятой;26- в противном случае оба должны быть целыми числами, и преобразование не требуется.2728Для некоторых операторов применяются дополнительные правила (например, строка в качестве левого аргумента оператора «%»). Расширения должны определять собственное поведение преобразования.2930## 6.2. Атомы3132Атомы – это самые базовые элементы выражений. Простейшие атомы – идентификаторы или литералы. Формы, заключённые в круглые, квадратные или фигурные скобки, также синтаксически относятся к атомам. Синтаксис атомов:3334```3536atom ::= identifier | literal | enclosure37enclosure ::= parenth_form | list_display | dict_display | set_display38 | generator_expression | yield_atom39```4041### 6.2.1. Идентификаторы (Имена)4243Идентификатор, выступающий в роли атома, является именем. См. раздел [Идентификаторы и ключевые слова](https://python-all.ru/3.7/reference/lexical_analysis.html#identifiers) для лексического определения и раздел [Именование и связывание](https://python-all.ru/3.7/reference/executionmodel.html#naming) для документации по именованию и связыванию.4445Когда имя привязано к объекту, вычисление атома возвращает этот объект. Когда имя не привязано, попытка его вычисления вызывает [`NameError`](https://python-all.ru/3.7/library/exceptions.html#NameError) исключение.4647**Искажение имени приватного атрибута:** Когда идентификатор, текстуально встречающийся в определении класса, начинается с двух или более символов подчёркивания и не заканчивается двумя или более подчёркиваниями, он считается *приватным именем* этого класса. Приватные имена преобразуются в более длинную форму перед генерацией кода для них. Преобразование вставляет имя класса, с удалёнными ведущими подчёркиваниями и одним вставленным подчёркиванием, перед именем. Например, идентификатор `__spam`, встречающийся в классе с именем `Ham`, будет преобразован в `_Ham__spam`. Это преобразование не зависит от синтаксического контекста, в котором используется идентификатор. Если преобразованное имя слишком длинное (длиннее 255 символов), может произойти усечение, определяемое реализацией. Если имя класса состоит только из подчёркиваний, преобразование не выполняется.4849### 6.2.2. Литералы5051Python поддерживает строковые литералы, литералы bytes и различные числовые литералы:5253```5455literal ::= stringliteral | bytesliteral56 | integer | floatnumber | imagnumber57```5859Вычисление литерала даёт объект указанного типа (строка, bytes, целое число, число с плавающей запятой, комплексное число) с указанным значением. Значение может быть приближённым для литералов с плавающей запятой и мнимых (комплексных). Подробнее см. раздел [Литералы](https://python-all.ru/3.7/reference/lexical_analysis.html#literals).6061Все литералы соответствуют неизменяемым типам данных, поэтому тождественность объекта менее важна, чем его значение. При многократном вычислении литералов с одинаковым значением (одного и того же или разных вхождений в тексте программы) может получаться как один и тот же объект, так и разные объекты с одним и тем же значением.6263### 6.2.3. Выражения в скобках6465Выражение в скобках – это необязательный список выражений, заключённый в круглые скобки:6667```6869parenth_form ::= "(" [starred_expression] ")"70```7172Вычисление списка выражений в скобках даёт результат этого списка: если список содержит хотя бы одну запятую, получается кортеж; в противном случае – единственное выражение, из которого состоит список.7374Пустая пара скобок даёт пустой кортеж. Поскольку кортежи неизменяемы, действуют те же правила, что и для литералов (два вхождения пустого кортежа могут как совпадать, так и не совпадать как объекты).7576Обратите внимание, что кортежи образуются не круглыми скобками, а использованием оператора запятой. Исключением является пустой кортеж, для которого круглые скобки *требуются* – разрешение «ничего» без скобок в выражениях привело бы к неоднозначностям и позволило бы распространённым опечаткам остаться незамеченными.7778### 6.2.4. Отображения для списков, множеств и словарей7980Для создания списка, множества или словаря в Python предусмотрен специальный синтаксис, называемый «отображениями» (displays); каждый из них существует в двух вариантах:8182- либо содержимое контейнера перечисляется явно, либо83- они вычисляются с помощью набора инструкций циклов и фильтрации, называемого *включением (comprehension)*.8485Общие синтаксические элементы для включений:8687```8889comprehension ::= expression comp_for90comp_for ::= ["async"] "for" target_list "in" or_test [comp_iter]91comp_iter ::= comp_for | comp_if92comp_if ::= "if" expression_nocond [comp_iter]93```9495Включение состоит из одного выражения, за которым следует по крайней мере одно предложение `for` и ноль или более предложений `for` или `if`. В этом случае элементами нового контейнера будут те, которые получаются при рассмотрении каждого из предложений `for` или `if` как блока, с вложением слева направо, и вычислении выражения для получения элемента каждый раз, когда достигается самый внутренний блок.9697Однако, за исключением итерируемого выражения в самом левом предложении `for`, включение выполняется в отдельной неявно вложенной области видимости. Это гарантирует, что имена, присваиваемые в целевом списке, не «утекают» в окружающую область.9899Итерируемое выражение в самом левом предложении `for` вычисляется непосредственно в объемлющей области видимости, а затем передаётся как аргумент в неявно вложенную область видимости. Последующие предложения `for` и любое условие фильтрации в самом левом предложении `for` не могут быть вычислены в объемлющей области видимости, поскольку могут зависеть от значений, полученных из самого левого итерируемого объекта. Например: `[x*y for x in range(10) for y in range(x, x+10)]`.100101Чтобы гарантировать, что включение (comprehension) всегда приводит к контейнеру подходящего типа, выражения `yield` и `yield from` запрещены в неявно вложенной области видимости (в Python 3.7 такие выражения при компиляции порождают [`DeprecationWarning`](https://python-all.ru/3.7/library/exceptions.html#DeprecationWarning), а в Python 3.8+ будут порождать [`SyntaxError`](https://python-all.ru/3.7/library/exceptions.html#SyntaxError)).102103Начиная с Python 3.6, в [`async def`](https://python-all.ru/3.7/reference/compound_stmts.html#async-def)-функции предложение `async for` может использоваться для итерации по [асинхронному итератору](https://python-all.ru/3.7/glossary.html#term-asynchronous-iterator). Включение в `async def`-функции может состоять из предложения `for` или `async for` после ведущего выражения, может содержать дополнительные предложения `for` или `async for`, а также может использовать выражения [`await`](https://python-all.ru/3.7/reference/expressions.html#await). Если включение содержит предложения `async for` или выражения `await`, оно называется *асинхронным включением*. Асинхронное включение может приостанавливать выполнение корутинной функции, в которой оно находится. См. также [**PEP 530**](https://python-all.ru/3.7/reference/expressions.html).104105Новое в версии 3.6: Были введены асинхронные выражения-генераторы.106107Устарело с версии 3.7: `yield` и `yield from` устарели в неявно вложенной области видимости.108109### 6.2.5. Списковые отображения110111Списковое отображение – это возможно пустая последовательность выражений, заключённая в квадратные скобки:112113```114115list_display ::= "[" [starred_list | comprehension] "]"116```117118Списковое отображение возвращает новый объект списка, содержимое которого задаётся либо списком выражений, либо включением. Если предоставлен разделённый запятыми список выражений, его элементы вычисляются слева направо и помещаются в объект списка в том же порядке. Если предоставлено включение, список строится из элементов, полученных в результате включения.119120### 6.2.6. Множественные отображения121122Множественное отображение обозначается фигурными скобками и отличается от словарных отображений отсутствием двоеточий, разделяющих ключи и значения:123124```125126set_display ::= "{" (starred_list | comprehension) "}"127```128129Множественное отображение возвращает новый изменяемый объект множества, содержимое которого задаётся либо последовательностью выражений, либо включением. Если предоставлен разделённый запятыми список выражений, его элементы вычисляются слева направо и добавляются в объект множества. Если предоставлено включение, множество строится из элементов, полученных в результате включения.130131Пустое множество нельзя создать с помощью `{}`; этот литерал создаёт пустой словарь.132133### 6.2.7. Словарные отображения134135Отображение словаря – это возможно пустая последовательность пар ключ/значение, заключённая в фигурные скобки:136137```138139dict_display ::= "{" [key_datum_list | dict_comprehension] "}"140key_datum_list ::= key_datum ("," key_datum)* [","]141key_datum ::= expression ":" expression | "**" or_expr142dict_comprehension ::= expression ":" expression comp_for143```144145Словарное отображение возвращает новый объект словаря.146147Если задана разделённая запятыми последовательность пар ключ/значение, они вычисляются слева направо для определения записей словаря: каждый объект ключа используется как ключ в словаре для хранения соответствующего значения. Это означает, что можно указать один и тот же ключ несколько раз в списке ключ/значение, и итоговое значение словаря для этого ключа будет последним указанным.148149Двойная звёздочка `**` обозначает *распаковку словаря*. Её операндом должно быть [отображение](https://python-all.ru/3.7/glossary.html#term-mapping). Каждый элемент отображения добавляется в новый словарь. Более поздние значения заменяют значения, уже установленные более ранними парами ключ/значение и более ранними распаковками словарей.150151Новое в версии 3.5: Распаковка в отображения словарей, изначально предложенная в [**PEP 448**](https://python-all.ru/3.7/reference/expressions.html).152153Словарное включение, в отличие от списковых и множественных включений, требует двух выражений, разделённых двоеточием, после которых следуют обычные предложения «for» и «if». При выполнении включения результирующие элементы ключей и значений вставляются в новый словарь в порядке их получения.154155Ограничения на типы ключей перечислены ранее в разделе [Стандартная иерархия типов](https://python-all.ru/3.7/reference/datamodel.html#types). (Кратко: тип ключа должен быть [хешируемым](https://python-all.ru/3.7/glossary.html#term-hashable), что исключает все изменяемые объекты.) Конфликты между дублирующимися ключами не обнаруживаются; последнее значение (текстуально самое правое в отображении), сохранённое для данного ключа, побеждает.156157### 6.2.8. Генераторные выражения158159Генераторное выражение – это компактная запись генератора в круглых скобках:160161```162163generator_expression ::= "(" expression comp_for ")"164```165166Генераторное выражение возвращает новый объект-генератор. Его синтаксис такой же, как у включений, за исключением того, что оно заключается в круглые скобки вместо квадратных или фигурных.167168Переменные, используемые в генераторном выражении, вычисляются лениво при вызове метода [`__next__()`](https://python-all.ru/3.7/reference/expressions.html#generator.__next__) для объекта-генератора (так же, как и в обычных генераторах). Однако выражение итерируемого объекта в самой левой части `for` вычисляется немедленно, поэтому ошибка, возникшая в нём, будет выдана в точке определения генераторного выражения, а не при получении первого значения. Последующие части `for` и любое условие фильтрации в самой левой части `for` не могут быть вычислены во внешней области видимости, поскольку они могут зависеть от значений, полученных из самого левого итерируемого объекта. Например: `(x*y for x in range(10) for y in range(x, x+10))`.169170Круглые скобки можно опускать при вызовах с одним аргументом. Подробнее см. раздел [Вызовы](https://python-all.ru/3.7/reference/expressions.html#calls).171172Чтобы не нарушать ожидаемую работу самого генераторного выражения, выражения `yield` и `yield from` запрещены в неявно определённом генераторе (в Python 3.7 такие выражения при компиляции порождают [`DeprecationWarning`](https://python-all.ru/3.7/library/exceptions.html#DeprecationWarning), а в Python 3.8+ будут порождать [`SyntaxError`](https://python-all.ru/3.7/library/exceptions.html#SyntaxError)).173174Если генераторное выражение содержит части `async for` или выражения [`await`](https://python-all.ru/3.7/reference/expressions.html#await), оно называется *асинхронным генераторным выражением*. Асинхронное генераторное выражение возвращает новый объект асинхронного генератора, который является асинхронным итератором (см. [Асинхронные итераторы](https://python-all.ru/3.7/reference/datamodel.html#async-iterators)).175176Новое в версии 3.6: Были введены асинхронные генераторные выражения.177178Изменено в версии 3.7: До Python 3.7 асинхронные generator-выражения могли появляться только в корутинах [`async def`](https://python-all.ru/3.7/reference/compound_stmts.html#async-def). Начиная с версии 3.7 любая функция может использовать асинхронные generator-выражения.179180Устарело с версии 3.7: `yield` и `yield from` устарели в неявно вложенной области видимости.181182### 6.2.9. Выражения yield183184```185186yield_atom ::= "(" yield_expression ")"187yield_expression ::= "yield" [expression_list | "from" expression]188```189190Выражение yield используется при определении [функции-генератора](https://python-all.ru/3.7/glossary.html#term-generator) или [асинхронной функции-генератора](https://python-all.ru/3.7/glossary.html#term-asynchronous-generator), и поэтому может находиться только в теле определения функции. Использование выражения yield в теле функции делает её генератором, а использование в теле [`async def`](https://python-all.ru/3.7/reference/compound_stmts.html#async-def) функции превращает эту корутинную функцию в асинхронный генератор. Например:191192```python193def gen(): # определяет функцию-генератор194 yield 123195196async def agen(): # определяет асинхронную функцию-генератор197 yield 123198```199200Из-за их побочных эффектов на содержащую область видимости, выражения `yield` не разрешены как часть неявно определённых областей видимости, используемых для реализации включений (comprehensions) и генераторных выражений (в Python 3.7 такие выражения при компиляции порождают [`DeprecationWarning`](https://python-all.ru/3.7/library/exceptions.html#DeprecationWarning), а в Python 3.8+ они будут порождать [`SyntaxError`](https://python-all.ru/3.7/library/exceptions.html#SyntaxError))..201202Устарело с версии 3.7: Выражения yield устарели в неявно вложенных областях видимости, используемых для реализации включений (comprehensions) и генераторных выражений.203204Generator functions are described below, while asynchronous generator functions are described separately in section [Asynchronous generator functions](https://python-all.ru/3.7/reference/expressions.html#asynchronous-generator-functions).205206Когда вызывается генераторная функция, она возвращает итератор, называемый генератором. Затем этот генератор управляет выполнением генераторной функции. Выполнение начинается, когда вызывается один из методов генератора. В этот момент выполнение переходит к первому выражению yield, где оно снова приостанавливается, возвращая значение [`expression_list`](https://python-all.ru/3.7/reference/expressions.html#grammar-token-expression-list) вызывающей стороне генератора. Под приостановкой подразумевается, что сохраняется всё локальное состояние, включая текущие привязки локальных переменных, указатель инструкции, внутренний стек вычислений и состояние обработки исключений. Когда выполнение возобновляется вызовом одного из методов генератора, функция может продолжить работу так, как если бы выражение yield было просто очередным внешним вызовом. Значение выражения yield после возобновления зависит от метода, который возобновил выполнение. Если используется [`__next__()`](https://python-all.ru/3.7/reference/expressions.html#generator.__next__) (обычно через [`for`](https://python-all.ru/3.7/reference/compound_stmts.html#for) или встроенную функцию [`next()`](https://python-all.ru/3.7/library/functions.html#next)), то результатом будет [`None`](https://python-all.ru/3.7/library/constants.html#None). В противном случае, если используется [`send()`](https://python-all.ru/3.7/reference/expressions.html#generator.send), результатом будет значение, переданное этому методу.207208Всё это делает функции-генераторы весьма похожими на корутины; они могут выдавать значения несколько раз, имеют более одной точки входа, и их выполнение может быть приостановлено. Единственное отличие в том, что функция-генератор не может управлять тем, где должно продолжиться выполнение после yield; управление всегда передаётся вызывающему generator.209210Выражения yield разрешены в любом месте конструкции [`try`](https://python-all.ru/3.7/reference/compound_stmts.html#try). Если generator не возобновляется до его завершения (достижение нулевого счётчика ссылок или сборка мусора), будет вызван метод [`close()`](https://python-all.ru/3.7/reference/expressions.html#generator.close) generator-итератора, что позволит выполнить все ожидающие предложения [`finally`](https://python-all.ru/3.7/reference/compound_stmts.html#finally).211212Когда используется `yield from <expr>`, он обрабатывает предоставленное выражение как субитератор. Все значения, полученные от этого субитератора, передаются напрямую вызывающему методы текущего генератора. Любые значения, переданные с помощью [`send()`](https://python-all.ru/3.7/reference/expressions.html#generator.send), и любые исключения, переданные с помощью [`throw()`](https://python-all.ru/3.7/reference/expressions.html#generator.throw), передаются нижележащему итератору, если он имеет соответствующие методы. Если это не так, то [`send()`](https://python-all.ru/3.7/reference/expressions.html#generator.send) вызовет [`AttributeError`](https://python-all.ru/3.7/library/exceptions.html#AttributeError) или [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError), а [`throw()`](https://python-all.ru/3.7/reference/expressions.html#generator.throw) просто сразу вызовет переданное исключение.213214Когда базовый итератор завершён, атрибут `value` возбуждённого экземпляра [`StopIteration`](https://python-all.ru/3.7/library/exceptions.html#StopIteration) становится значением выражения yield. Он может быть установлен явно при возбуждении [`StopIteration`](https://python-all.ru/3.7/library/exceptions.html#StopIteration) или автоматически, когда под-итератор является generator (путём возврата значения из под-генератора).215216> Изменено в версии 3.3: Добавлено `yield from <expr>` для делегирования потока управления под-итератору.217218Круглые скобки могут быть опущены, когда выражение yield является единственным выражением в правой части оператора присваивания.219220> **См. также**221>222> **[**PEP 255**](https://python-all.ru/3.7/reference/expressions.html) - Simple Generators**223>224> Предложение по добавлению генераторов и оператора [`yield`](https://python-all.ru/3.7/reference/simple_stmts.html#yield) в Python.225>226> **[**PEP 342**](https://python-all.ru/3.7/reference/expressions.html) - Coroutines via Enhanced Generators**227>228> Предложение по улучшению API и синтаксиса генераторов, позволяющее использовать их как простые корутины.229>230> **[**PEP 380**](https://python-all.ru/3.7/reference/expressions.html) - Syntax for Delegating to a Subgenerator**231>232> Предложение по вводу синтаксиса `yield_from`, упрощающее делегирование подгенераторам.233>234> **[**PEP 525**](https://python-all.ru/3.7/reference/expressions.html) - Asynchronous Generators**235>236> The proposal that expanded on [**PEP 492**](https://python-all.ru/3.7/reference/expressions.html) by adding generator capabilities to coroutine functions.237238#### 6.2.9.1. Методы generator-итератора239240В этом подразделе описаны методы итератора генератора. Они могут использоваться для управления выполнением генераторной функции.241242Обратите внимание, что вызов любого из приведённых ниже методов генератора, когда генератор уже выполняется, приводит к исключению [`ValueError`](https://python-all.ru/3.7/library/exceptions.html#ValueError).243244#### `generator.__next__()`245246Запускает выполнение генераторной функции или возобновляет его на последнем выполненном выражении yield. Когда генераторная функция возобновляется методом [`__next__()`](https://python-all.ru/3.7/reference/expressions.html#generator.__next__), текущее выражение yield всегда вычисляется в [`None`](https://python-all.ru/3.7/library/constants.html#None). Затем выполнение переходит к следующему выражению yield, где генератор снова приостанавливается, и значение [`expression_list`](https://python-all.ru/3.7/reference/expressions.html#grammar-token-expression-list) возвращается вызывающей стороне [`__next__()`](https://python-all.ru/3.7/reference/expressions.html#generator.__next__). Если генератор завершается, не вернув другого значения, возбуждается исключение [`StopIteration`](https://python-all.ru/3.7/library/exceptions.html#StopIteration).247248Обычно этот метод вызывается неявно, например, циклом [`for`](https://python-all.ru/3.7/reference/compound_stmts.html#for) или встроенной функцией [`next()`](https://python-all.ru/3.7/library/functions.html#next).249250#### `generator.send(value)`251252Возобновляет выполнение и «отправляет» значение в генераторную функцию. Аргумент *value* становится результатом текущего выражения yield. Метод [`send()`](https://python-all.ru/3.7/reference/expressions.html#generator.send) возвращает следующее значение, выданное генератором, или возбуждает [`StopIteration`](https://python-all.ru/3.7/library/exceptions.html#StopIteration), если генератор завершается, не выдав другого значения. При вызове [`send()`](https://python-all.ru/3.7/reference/expressions.html#generator.send) для запуска генератора его необходимо вызывать с аргументом [`None`](https://python-all.ru/3.7/library/constants.html#None), так как нет выражения yield, которое могло бы получить значение.253254#### `generator.throw(type[, value[, traceback]])`255256Вызывает исключение типа `type` в точке, где генератор был приостановлен, и возвращает следующее значение, выданное функцией-генератором. Если генератор завершается, не выдав другого значения, возбуждается исключение [`StopIteration`](https://python-all.ru/3.7/library/exceptions.html#StopIteration). Если функция-генератор не перехватывает переданное исключение или возбуждает другое исключение, то это исключение передаётся вызывающему коду.257258#### `generator.close()`259260Возбуждает [`GeneratorExit`](https://python-all.ru/3.7/library/exceptions.html#GeneratorExit) в точке, где была приостановлена функция-генератор. Если после этого функция-генератор завершается штатно, уже закрыта или возбуждает [`GeneratorExit`](https://python-all.ru/3.7/library/exceptions.html#GeneratorExit) (не перехватывая исключение), close возвращается к вызвавшему коду. Если генератор выдает значение, возбуждается [`RuntimeError`](https://python-all.ru/3.7/library/exceptions.html#RuntimeError). Если генератор возбуждает любое другое исключение, оно передается вызвавшему коду. [`close()`](https://python-all.ru/3.7/reference/expressions.html#generator.close) ничего не делает, если генератор уже завершился из-за исключения или штатно.261262#### 6.2.9.2. Примеры263264Вот простой пример, демонстрирующий поведение генераторов и генераторных функций:265266```python267>>> def echo(value=None):268... print("Execution starts when 'next()' is called for the first time.")269... try:270... while True:271... try:272... value = (yield value)273... except Exception as e:274... value = e275... finally:276... print("Don't forget to clean up when 'close()' is called.")277...278>>> generator = echo(1)279>>> print(next(generator))280Execution starts when 'next()' is called for the first time.2811282>>> print(next(generator))283None284>>> print(generator.send(2))2852286>>> generator.throw(TypeError, "spam")287TypeError('spam',)288>>> generator.close()289Don't forget to clean up when 'close()' is called.290```291292Примеры использования `yield from` см. в [PEP 380: Syntax for Delegating to a Subgenerator](https://python-all.ru/3.7/whatsnew/3.3.html#pep-380) в разделе «What’s New in Python».293294#### 6.2.9.3. Асинхронные генераторные функции295296Наличие выражения yield в функции или методе, определённом с помощью [`async def`](https://python-all.ru/3.7/reference/compound_stmts.html#async-def), дополнительно определяет функцию как [асинхронный генератор](https://python-all.ru/3.7/glossary.html#term-asynchronous-generator).297298При вызове асинхронной генераторной функции она возвращает асинхронный итератор, известный как объект асинхронного генератора. Этот объект затем управляет выполнением генераторной функции. Объект асинхронного генератора обычно используется в инструкции [`async for`](https://python-all.ru/3.7/reference/compound_stmts.html#async-for) внутри корутинной функции, аналогично тому, как объект генератора используется в инструкции [`for`](https://python-all.ru/3.7/reference/compound_stmts.html#for).299300Вызов одного из методов асинхронного генератора возвращает объект [ожидаемый объект](https://python-all.ru/3.7/glossary.html#term-awaitable), и выполнение начинается, когда этот объект ожидается. В этот момент выполнение переходит к первому выражению yield, где оно снова приостанавливается, возвращая значение [`expression_list`](https://python-all.ru/3.7/reference/expressions.html#grammar-token-expression-list) ожидающей корутине. Как и в случае с генератором, приостановка означает, что сохраняется всё локальное состояние, включая текущие привязки локальных переменных, указатель инструкции, внутренний стек вычислений и состояние обработки исключений. Когда выполнение возобновляется ожиданием следующего объекта, возвращённого методами асинхронного генератора, функция может продолжить работу так, как если бы выражение yield было просто очередным внешним вызовом. Значение выражения yield после возобновления зависит от метода, который возобновил выполнение. Если используется [`__anext__()`](https://python-all.ru/3.7/reference/expressions.html#agen.__anext__), то результатом будет [`None`](https://python-all.ru/3.7/library/constants.html#None). В противном случае, если используется [`asend()`](https://python-all.ru/3.7/reference/expressions.html#agen.asend), результатом будет значение, переданное этому методу.301302В асинхронной генераторной функции выражения yield разрешены в любом месте конструкции [`try`](https://python-all.ru/3.7/reference/compound_stmts.html#try). Однако если асинхронный генератор не был возобновлён до финализации (достижение нулевого счётчика ссылок или сборка мусора), то выражение yield внутри конструкции `try` может привести к невозможности выполнить ожидающие предложения [`finally`](https://python-all.ru/3.7/reference/compound_stmts.html#finally). В этом случае цикл событий или планировщик, выполняющий асинхронный генератор, должен вызвать метод [`aclose()`](https://python-all.ru/3.7/reference/expressions.html#agen.aclose) итератора асинхронного генератора и запустить полученный объект корутины, чтобы позволить выполниться ожидающим предложениям `finally`.303304Для обработки завершения цикл событий должен определить функцию *финализатор*, которая принимает асинхронный генератор-итератор и, предположительно, вызывает [`aclose()`](https://python-all.ru/3.7/reference/expressions.html#agen.aclose) и выполняет корутину. Этот *финализатор* может быть зарегистрирован вызовом [`sys.set_asyncgen_hooks()`](https://python-all.ru/3.7/library/sys.html#sys.set_asyncgen_hooks). При первом итерировании асинхронный генератор-итератор сохраняет зарегистрированный *финализатор* для вызова при завершении. Пример реализации метода *финализатор* см. в реализации `asyncio.Loop.shutdown_asyncgens` в [Lib/asyncio/base\_events.py](https://python-all.ru/src/3.7/Lib/asyncio/base_events.py).305306Выражение `yield from <expr>` является синтаксической ошибкой при использовании в асинхронной генераторной функции.307308#### 6.2.9.4. Методы итератора асинхронного генератора309310В этом подразделе описаны методы итератора асинхронного генератора, которые используются для управления выполнением генераторной функции.311312#### `coroutine agen.__anext__()`313314Возвращает ожидаемый объект, который при запуске начинает выполнение асинхронного генератора или возобновляет его на последнем выполненном выражении yield. Когда асинхронная генераторная функция возобновляется методом [`__anext__()`](https://python-all.ru/3.7/reference/expressions.html#agen.__anext__), текущее выражение yield всегда вычисляется в [`None`](https://python-all.ru/3.7/library/constants.html#None) в возвращаемом ожидаемом объекте, который при запуске переходит к следующему выражению yield. Значение [`expression_list`](https://python-all.ru/3.7/reference/expressions.html#grammar-token-expression-list) выражения yield – это значение исключения [`StopIteration`](https://python-all.ru/3.7/library/exceptions.html#StopIteration), возбуждённого завершающей корутиной. Если асинхронный генератор завершается, не вернув другого значения, ожидаемый объект вместо этого возбуждает исключение [`StopAsyncIteration`](https://python-all.ru/3.7/library/exceptions.html#StopAsyncIteration), сигнализируя о завершении асинхронной итерации.315316Обычно этот метод вызывается неявно циклом [`async for`](https://python-all.ru/3.7/reference/compound_stmts.html#async-for).317318#### `coroutine agen.asend(value)`319320Возвращает ожидаемый объект, который при запуске возобновляет выполнение асинхронного генератора. Как и в случае метода [`send()`](https://python-all.ru/3.7/reference/expressions.html#generator.send) для генератора, этот «отправляет» значение в асинхронную функцию-генератор, и аргумент *value* становится результатом текущего выражения yield. Ожидаемый объект, возвращённый методом [`asend()`](https://python-all.ru/3.7/reference/expressions.html#agen.asend), вернёт следующее значение, выданное генератором, как значение возбуждённого [`StopIteration`](https://python-all.ru/3.7/library/exceptions.html#StopIteration), или возбуждает [`StopAsyncIteration`](https://python-all.ru/3.7/library/exceptions.html#StopAsyncIteration), если асинхронный генератор завершится, не выдав другого значения. Когда [`asend()`](https://python-all.ru/3.7/reference/expressions.html#agen.asend) вызывается для запуска асинхронного генератора, он должен быть вызван с аргументом [`None`](https://python-all.ru/3.7/library/constants.html#None), потому что нет выражения yield, которое могло бы получить значение.321322#### `coroutine agen.athrow(value)`323324#### `coroutine agen.athrow(type[, value[, traceback]])`325326Возвращает ожидаемый объект, который возбуждает исключение типа `type` в точке, где асинхронный генератор был приостановлен, и возвращает следующее значение, выданное функцией-генератором, как значение возбуждённого исключения [`StopIteration`](https://python-all.ru/3.7/library/exceptions.html#StopIteration). Если асинхронный генератор завершается, не выдав другого значения, ожидаемый объект возбуждает исключение [`StopAsyncIteration`](https://python-all.ru/3.7/library/exceptions.html#StopAsyncIteration). Если функция-генератор не перехватывает переданное исключение или возбуждает другое исключение, то при запуске ожидаемого объекта это исключение распространяется на вызывающую сторону.327328#### `coroutine agen.aclose()`329330Возвращает ожидаемый объект, который при запуске вызовет [`GeneratorExit`](https://python-all.ru/3.7/library/exceptions.html#GeneratorExit) в асинхронную функцию-генератор в точке, где она была приостановлена. Если асинхронная функция-генератор затем завершается нормально, уже закрыта или возбуждает [`GeneratorExit`](https://python-all.ru/3.7/library/exceptions.html#GeneratorExit) (не перехватив исключение), то возвращаемый ожидаемый объект возбудит исключение [`StopIteration`](https://python-all.ru/3.7/library/exceptions.html#StopIteration). Любые последующие ожидаемые объекты, возвращённые вызовами асинхронного генератора, будут возбуждать исключение [`StopAsyncIteration`](https://python-all.ru/3.7/library/exceptions.html#StopAsyncIteration). Если асинхронный генератор выдаёт значение, ожидаемый объект возбуждает [`RuntimeError`](https://python-all.ru/3.7/library/exceptions.html#RuntimeError). Если асинхронный генератор возбуждает любое другое исключение, оно распространяется на вызывающую сторону ожидаемого объекта. Если асинхронный генератор уже завершился по причине исключения или нормального завершения, то последующие вызовы [`aclose()`](https://python-all.ru/3.7/reference/expressions.html#agen.aclose) возвратят ожидаемый объект, который ничего не делает.331332## 6.3. Первичные выражения333334Первичные выражения представляют операции с самой высокой связностью в языке. Их синтаксис:335336```337338primary ::= atom | attributeref | subscription | slicing | call339```340341### 6.3.1. Ссылки на атрибуты342343Ссылка на атрибут – это первичное выражение, за которым следуют точка и имя:344345```346347attributeref ::= primary "." identifier348```349350Первичное выражение должно вычисляться в объект типа, который поддерживает ссылки на атрибуты (большинство объектов это делают). Затем у этого объекта запрашивается атрибут, имя которого является идентификатором. Это получение можно настроить, переопределив метод [`__getattr__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getattr__). Если такой атрибут недоступен, возбуждается исключение [`AttributeError`](https://python-all.ru/3.7/library/exceptions.html#AttributeError). В противном случае тип и значение полученного объекта определяются объектом. Многократные вычисления одной и той же ссылки на атрибут могут давать разные объекты.351352### 6.3.2. Индексация353354Индексация выбирает элемент последовательности (строки, кортежа или списка) или отображения (словаря):355356```357358subscription ::= primary "[" expression_list "]"359```360361Первичное выражение должно вычисляться в объект, поддерживающий индексацию (например, списки или словари). Пользовательские объекты могут поддерживать индексацию, определив метод [`__getitem__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getitem__).362363Для встроенных объектов существует два типа объектов, поддерживающих индексацию:364365Если первичное выражение является отображением, список выражений должен вычисляться в объект, значение которого является одним из ключей отображения, и индексация выбирает значение в отображении, соответствующее этому ключу. (Список выражений представляет собой кортеж, за исключением случая, когда он содержит ровно один элемент.)366367Если первичное выражение является последовательностью, список выражений должен вычисляться в целое число или срез (как описано в следующем разделе).368369Формальный синтаксис не предусматривает особой обработки отрицательных индексов для последовательностей; однако все встроенные последовательности предоставляют метод [`__getitem__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getitem__), который интерпретирует отрицательные индексы, прибавляя длину последовательности к индексу (так что `x[-1]` выбирает последний элемент `x`). Полученное значение должно быть неотрицательным целым числом, меньшим количества элементов в последовательности, и индексация выбирает элемент с этим индексом (начиная с нуля). Поскольку поддержка отрицательных индексов и срезов реализована в методе [`__getitem__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getitem__) объекта, подклассы, переопределяющие этот метод, должны явно добавлять эту поддержку.370371Элементами строки являются символы. Символ не является отдельным типом данных, а представляет собой строку ровно из одного символа.372373### 6.3.3. Срезы374375Срез выбирает диапазон элементов в объекте-последовательности (например, строке, кортеже или списке). Срезы могут использоваться как выражения или как цели в операторах присваивания или [`del`](https://python-all.ru/3.7/reference/simple_stmts.html#del). Синтаксис среза:376377```378379slicing ::= primary "[" slice_list "]"380slice_list ::= slice_item ("," slice_item)* [","]381slice_item ::= expression | proper_slice382proper_slice ::= [lower_bound] ":" [upper_bound] [ ":" [stride] ]383lower_bound ::= expression384upper_bound ::= expression385stride ::= expression386```387388В формальном синтаксисе здесь есть неоднозначность: всё, что выглядит как список выражений, также выглядит как список срезов, поэтому любую индексацию можно интерпретировать как срез. Чтобы не усложнять синтаксис, эта неоднозначность разрешается тем, что в данном случае интерпретация как индексация имеет приоритет над интерпретацией как срез (это верно, если список срезов не содержит полноценного среза).389390Семантика среза следующая. Первичный объект индексируется (с использованием того же метода [`__getitem__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getitem__), что и для обычной индексации) ключом, который строится из списка срезов следующим образом. Если список срезов содержит хотя бы одну запятую, ключом является кортеж, содержащий преобразованные элементы среза; в противном случае ключом является преобразованный единственный элемент среза. Преобразование элемента среза, являющегося выражением, – это само выражение. Преобразование полноценного среза – это объект среза (см. раздел [Стандартная иерархия типов](https://python-all.ru/3.7/reference/datamodel.html#types)), чьи атрибуты `start`, `stop` и `step` являются значениями выражений, заданных как нижняя граница, верхняя граница и шаг соответственно, с подстановкой `None` для отсутствующих выражений.391392### 6.3.4. Вызовы393394Вызов – это обращение к вызываемому объекту (например, [функции](https://python-all.ru/3.7/glossary.html#term-function)) с возможно пустой последовательностью [аргументов](https://python-all.ru/3.7/glossary.html#term-argument):395396```397398call ::= primary "(" [argument_list [","] | comprehension] ")"399argument_list ::= positional_arguments ["," starred_and_keywords]400 ["," keywords_arguments]401 | starred_and_keywords ["," keywords_arguments]402 | keywords_arguments403positional_arguments ::= ["*"] expression ("," ["*"] expression)*404starred_and_keywords ::= ("*" expression | keyword_item)405 ("," "*" expression | "," keyword_item)*406keywords_arguments ::= (keyword_item | "**" expression)407 ("," keyword_item | "," "**" expression)*408keyword_item ::= identifier "=" expression409```410411После позиционных и именованных аргументов может стоять необязательная завершающая запятая, но на семантику это не влияет.412413Первичное выражение должно принимать значение вызываемого объекта (вызываемыми являются: функции, определённые пользователем, встроенные функции, методы встроенных объектов, объекты классов, методы экземпляров классов и все объекты, имеющие метод [`__call__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__call__)). Все выражения аргументов вычисляются до попытки вызова. За синтаксисом списков формальных [параметров](https://python-all.ru/3.7/glossary.html#term-parameter) обращайтесь к разделу [Определения функций](https://python-all.ru/3.7/reference/compound_stmts.html#function).414415Если присутствуют именованные аргументы, они сначала преобразуются в позиционные следующим образом. Сначала создаётся список незаполненных слотов для формальных параметров. Если есть N позиционных аргументов, они помещаются в первые N слотов. Затем для каждого именованного аргумента идентификатор используется для определения соответствующего слота (если идентификатор совпадает с именем первого формального параметра, используется первый слот, и т.д.). Если слот уже заполнен, возбуждается исключение [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError). В противном случае значение аргумента помещается в слот, заполняя его (даже если выражение равно `None`, оно всё равно заполняет слот). Когда все аргументы обработаны, слоты, которые всё ещё не заполнены, заполняются соответствующим значением по умолчанию из определения функции. (Значения по умолчанию вычисляются один раз при определении функции; таким образом, изменяемый объект, такой как список или словарь, используемый в качестве значения по умолчанию, будет разделяться между всеми вызовами, которые не указывают значение аргумента для соответствующего слота; этого обычно следует избегать.) Если есть незаполненные слоты, для которых не указано значение по умолчанию, возбуждается исключение [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError). В противном случае список заполненных слотов используется как список аргументов для вызова.416417**Особенность реализации CPython:** Реализация может предоставлять встроенные функции, чьи позиционные параметры не имеют имён, даже если они «названы» для целей документации, и поэтому их нельзя передать по ключевому слову. В CPython это относится к функциям, реализованным на C, которые используют [`PyArg_ParseTuple()`](https://python-all.ru/3.7/c-api/arg.html#c.PyArg_ParseTuple) для разбора своих аргументов.418419Если позиционных аргументов больше, чем слотов формальных параметров, возбуждается исключение [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError), если только не присутствует формальный параметр с синтаксисом `*identifier`; в этом случае этот формальный параметр получает кортеж, содержащий лишние позиционные аргументы (или пустой кортеж, если лишних позиционных аргументов не было).420421Если какой-либо именованный аргумент не соответствует имени формального параметра, возбуждается исключение [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError), если только не присутствует формальный параметр с синтаксисом `**identifier`; в этом случае этот формальный параметр получает словарь, содержащий лишние именованные аргументы (с ключами в качестве имён и значениями аргументов в качестве соответствующих значений), или (новый) пустой словарь, если лишних именованных аргументов не было.422423Если в вызове функции присутствует синтаксис `*expression`, `expression` должен принимать значение [итерируемого объекта](https://python-all.ru/3.7/glossary.html#term-iterable). Элементы из этих итерируемых объектов рассматриваются как дополнительные позиционные аргументы. Для вызова `f(x1, x2, *y, x3, x4)`, если *y* принимает значение последовательности *y1*, …, *yM*, это эквивалентно вызову с M+4 позиционными аргументами *x1*, *x2*, *y1*, …, *yM*, *x3*, *x4*.424425Следствием этого является то, что хотя синтаксис `*expression` может появляться *после* явных именованных аргументов, он обрабатывается *до* именованных аргументов (и любых аргументов `**expression` – см. ниже). Итак:426427```python428>>> def f(a, b):429... print(a, b)430...431>>> f(b=1, *(2,))4322 1433>>> f(a=1, *(2,))434Traceback (most recent call last):435 File "<stdin>", line 1, in <module>436TypeError: f() got multiple values for keyword argument 'a'437>>> f(1, *(2,))4381 2439```440441Использование одновременно именованных аргументов и синтаксиса `*expression` в одном вызове необычно, поэтому на практике такая путаница не возникает.442443Если в вызове функции присутствует синтаксис `**expression`, `expression` должно вычисляться в [отображение](https://python-all.ru/3.7/glossary.html#term-mapping), содержимое которого обрабатывается как дополнительные именованные аргументы. Если ключевое слово уже присутствует (как явный именованный аргумент или из другой распаковки), возбуждается исключение [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError).444445Формальные параметры с синтаксисом `*identifier` или `**identifier` не могут использоваться как слоты позиционных аргументов или как имена именованных аргументов.446447Изменено в версии 3.5: Вызовы функций принимают любое количество распаковок `*` и `**`, позиционные аргументы могут следовать за распаковками итерируемых объектов (`*`), а именованные аргументы – за распаковками словарей (`**`). Изначально предложено в [**PEP 448**](https://python-all.ru/3.7/reference/expressions.html).448449Вызов всегда возвращает некоторое значение, возможно `None`, если только не возбуждается исключение. Как вычисляется это значение, зависит от типа вызываемого объекта.450451Если это–452453**пользовательская функция:**454455Блок кода функции выполняется, ему передаётся список аргументов. Первое, что делает блок кода, – связывает формальные параметры с аргументами; это описано в разделе [Определения функций](https://python-all.ru/3.7/reference/compound_stmts.html#function). Когда блок кода выполняет инструкцию [`return`](https://python-all.ru/3.7/reference/simple_stmts.html#return), она задаёт возвращаемое значение вызова функции.456457**встроенная функция или метод:**458459Результат зависит от интерпретатора; описания встроенных функций и методов см. в [Встроенные функции](https://python-all.ru/3.7/library/functions.html#built-in-funcs).460461**объект класса:**462463Возвращается новый экземпляр этого класса.464465**метод экземпляра класса:**466467Вызывается соответствующая пользовательская функция, со списком аргументов, который на один длиннее списка аргументов вызова: экземпляр становится первым аргументом.468469**экземпляр класса:**470471Класс должен определять метод [`__call__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__call__); результат будет таким же, как если бы был вызван этот метод.472473## 6.4. Выражение await474475Приостанавливает выполнение [корутины](https://python-all.ru/3.7/glossary.html#term-coroutine) на [ожидаемом объекте](https://python-all.ru/3.7/glossary.html#term-awaitable). Может использоваться только внутри [корутинной функции](https://python-all.ru/3.7/glossary.html#term-coroutine-function).476477```478479await_expr ::= "await" primary480```481482Новое в версии 3.5.483484## 6.5. Оператор возведения в степень485486Оператор возведения в степень имеет более высокий приоритет, чем унарные операторы слева, и более низкий приоритет, чем унарные операторы справа. Синтаксис:487488```489490power ::= (await_expr | primary) ["**" u_expr]491```492493Таким образом, в последовательности операторов возведения в степень и унарных операторов без скобок операторы вычисляются справа налево (это не накладывает ограничений на порядок вычисления операндов): `-1**2` даёт `-1`.494495Оператор возведения в степень имеет ту же семантику, что и встроенная функция [`pow()`](https://python-all.ru/3.7/library/functions.html#pow), вызываемая с двумя аргументами: он возвращает левый аргумент, возведённый в степень правого аргумента. Числовые аргументы сначала преобразуются к общему типу, и результат имеет этот тип.496497Для операндов типа int результат имеет тот же тип, что и операнды, если только второй аргумент не отрицателен; в этом случае все аргументы преобразуются в float и возвращается результат типа float. Например, `10**2` возвращает `100`, но `10**-2` возвращает `0.01`.498499Возведение `0.0` в отрицательную степень приводит к [`ZeroDivisionError`](https://python-all.ru/3.7/library/exceptions.html#ZeroDivisionError). Возведение отрицательного числа в дробную степень даёт [`complex`](https://python-all.ru/3.7/library/functions.html#complex) число. (В более ранних версиях это вызывало [`ValueError`](https://python-all.ru/3.7/library/exceptions.html#ValueError).)500501## 6.6. Унарные арифметические и побитовые операции502503Все унарные арифметические и побитовые операции имеют одинаковый приоритет:504505```506507u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr508```509510Унарный оператор `-` (минус) возвращает отрицание своего числового аргумента.511512Унарный оператор `+` (плюс) возвращает свой числовой аргумент без изменений.513514Унарный оператор `~` (инверсия) возвращает побитовое инвертирование своего целочисленного аргумента. Побитовая инверсия `x` определяется как `-(x+1)`. Он применяется только к целым числам.515516Во всех трёх случаях, если аргумент имеет неправильный тип, вызывается исключение [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError).517518## 6.7. Бинарные арифметические операции519520Бинарные арифметические операции имеют общепринятые уровни приоритета. Обратите внимание, что некоторые из этих операций также применимы к некоторым нечисловым типам. За исключением оператора возведения в степень, существует только два уровня: один для мультипликативных операторов и один для аддитивных операторов:521522```523524m_expr ::= u_expr | m_expr "*" u_expr | m_expr "@" m_expr |525 m_expr "//" u_expr | m_expr "/" u_expr |526 m_expr "%" u_expr527a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr528```529530Оператор `*` (умножения) возвращает произведение своих аргументов. Аргументы должны быть либо оба числами, либо один аргумент – целым числом, а другой – последовательностью. В первом случае числа преобразуются к общему типу и затем перемножаются. Во втором случае выполняется повторение последовательности; отрицательный коэффициент повторения даёт пустую последовательность.531532Оператор `@` (at) предназначен для умножения матриц. Ни один встроенный тип Python не реализует этот оператор.533534Новое в версии 3.5.535536Операторы `/` (деления) и `//` (целочисленного деления) возвращают частное своих аргументов. Числовые аргументы сначала преобразуются к общему типу. Деление целых чисел даёт число с плавающей точкой, а целочисленное деление целых чисел даёт целое число; результат соответствует математическому делению с применением функции «floor» к результату. Деление на ноль вызывает исключение [`ZeroDivisionError`](https://python-all.ru/3.7/library/exceptions.html#ZeroDivisionError).537538Оператор `%` (остаток от деления) возвращает остаток от деления первого аргумента на второй. Числовые аргументы сначала преобразуются к общему типу. Нулевой правый аргумент вызывает исключение [`ZeroDivisionError`](https://python-all.ru/3.7/library/exceptions.html#ZeroDivisionError). Аргументы могут быть числами с плавающей запятой, например, `3.14%0.7` равно `0.34` (поскольку `3.14` равно `4*0.7 + 0.34`.) Оператор остатка всегда возвращает результат того же знака, что и его второй операнд (или ноль); абсолютное значение результата строго меньше абсолютного значения второго операнда [1](https://python-all.ru/3.7/reference/expressions.html#id17).539540Операторы целочисленного деления и остатка связаны следующим тождеством: `x == (x//y)*y + (x%y)`. Целочисленное деление и остаток также связаны со встроенной функцией [`divmod()`](https://python-all.ru/3.7/library/functions.html#divmod): `divmod(x, y) == (x//y, x%y)`. [2](https://python-all.ru/3.7/reference/expressions.html#id18).541542Помимо выполнения операции взятия остатка над числами, оператор `%` также перегружается строковыми объектами для выполнения форматирования строк в старом стиле (также известного как интерполяция). Синтаксис форматирования строк описан в справочнике по библиотеке Python, раздел [Форматирование строк в стиле printf](https://python-all.ru/3.7/library/stdtypes.html#old-string-formatting).543544Оператор целочисленного деления, оператор остатка от деления и функция [`divmod()`](https://python-all.ru/3.7/library/functions.html#divmod) не определены для комплексных чисел. Вместо этого преобразуйте их в число с плавающей запятой с помощью функции [`abs()`](https://python-all.ru/3.7/library/functions.html#abs), если это необходимо.545546Оператор `+` (сложения) возвращает сумму своих аргументов. Аргументы должны быть либо оба числами, либо оба последовательностями одного типа. В первом случае числа преобразуются к общему типу и затем складываются. Во втором случае последовательности конкатенируются.547548Оператор `-` (вычитания) возвращает разность своих аргументов. Числовые аргументы сначала преобразуются к общему типу.549550## 6.8. Операции сдвига551552Операции сдвига имеют более низкий приоритет, чем арифметические операции:553554```555556shift_expr ::= a_expr | shift_expr ("<<" | ">>") a_expr557```558559Эти операторы принимают целые числа в качестве аргументов. Они сдвигают первый аргумент влево или вправо на количество бит, заданное вторым аргументом.560561Правый сдвиг на *n* бит определяется как целочисленное деление на `pow(2,n)`. Левый сдвиг на *n* бит определяется как умножение на `pow(2,n)`.562563## 6.9. Двоичные побитовые операции564565Каждая из трёх побитовых операций имеет свой уровень приоритета:566567```568569and_expr ::= shift_expr | and_expr "&" shift_expr570xor_expr ::= and_expr | xor_expr "^" and_expr571or_expr ::= xor_expr | or_expr "|" xor_expr572```573574Оператор `&` возвращает побитовое И своих аргументов, которые должны быть целыми числами.575576Оператор `^` возвращает побитовое исключающее ИЛИ (XOR) своих аргументов, которые должны быть целыми числами.577578Оператор `|` возвращает побитовое (включающее) ИЛИ своих аргументов, которые должны быть целыми числами.579580## 6.10. Сравнения581582В отличие от C, все операции сравнения в Python имеют одинаковый приоритет, который ниже приоритета любых арифметических, сдвиговых или побитовых операций. Также в отличие от C, выражения вида `a < b < c` интерпретируются так, как принято в математике:583584```585586comparison ::= or_expr (comp_operator or_expr)*587comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="588 | "is" ["not"] | ["not"] "in"589```590591Сравнения возвращают логические значения: `True` или `False`.592593Сравнения можно произвольно объединять в цепочки, например, `x < y <= z` эквивалентно `x < y and y <= z`, за исключением того, что `y` вычисляется только один раз (но в обоих случаях `z` вообще не вычисляется, если `x < y` оказывается ложным).594595Формально, если *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`, за исключением того, что каждое выражение вычисляется не более одного раза.596597Обратите внимание, что `a op1 b op2 c` не подразумевает никакого сравнения между *a* и *c*, так что, например, `x < y > z` совершенно допустимо (хотя, возможно, и некрасиво).598599### 6.10.1. Сравнения значений600601Операторы `<`, `>`, `==`, `>=`, `<=` и `!=` сравнивают значения двух объектов. Объекты не обязательно должны иметь одинаковый тип.602603В главе [Объекты, значения и типы](https://python-all.ru/3.7/reference/datamodel.html#objects) говорится, что объекты имеют значение (в дополнение к типу и идентичности). Значение объекта – довольно абстрактное понятие в Python: например, не существует канонического метода доступа к значению объекта. Также не требуется, чтобы значение объекта было сформировано определённым образом, например, из всех его атрибутов данных. Операторы сравнения реализуют определённое представление о том, что является значением объекта. Можно считать, что они косвенно определяют значение объекта через свою реализацию сравнения.604605Поскольку все типы являются (прямыми или косвенными) подтипами [`object`](https://python-all.ru/3.7/library/functions.html#object), они наследуют поведение сравнения по умолчанию от [`object`](https://python-all.ru/3.7/library/functions.html#object). Типы могут настраивать своё поведение сравнения, реализуя *методы расширенного сравнения*, такие как [`__lt__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__lt__), описанные в разделе [Базовая настройка](https://python-all.ru/3.7/reference/datamodel.html#customization).606607Поведение по умолчанию для сравнения на равенство (`==` и `!=`) основано на идентичности объектов. Следовательно, сравнение на равенство экземпляров с одинаковой идентичностью даёт равенство, а сравнение экземпляров с разной идентичностью – неравенство. Мотивация такого поведения по умолчанию – желание, чтобы все объекты были рефлексивными (т.е. `x is y` влечёт `x == y`).608609Поведение сравнения порядка по умолчанию (`<`, `>`, `<=` и `>=`) не предусмотрено; попытка вызывает [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError). Мотивация такого поведения по умолчанию – отсутствие аналогичного инварианта, как для равенства.610611Поведение сравнения на равенство по умолчанию, при котором экземпляры с разной идентичностью всегда неравны, может противоречить тому, что нужно типам, имеющим разумное определение значения объекта и равенства на основе значения. Таким типам потребуется настраивать своё поведение сравнения, и, в самом деле, ряд встроенных типов уже это сделал.612613Следующий список описывает поведение сравнения наиболее важных встроенных типов.614615- Числа встроенных числовых типов ([Числовые типы – int, float, complex](https://python-all.ru/3.7/library/stdtypes.html#typesnumeric)) и типов стандартной библиотеки [`fractions.Fraction`](https://python-all.ru/3.7/library/fractions.html#fractions.Fraction) и [`decimal.Decimal`](https://python-all.ru/3.7/library/decimal.html#decimal.Decimal) можно сравнивать как внутри своих типов, так и между ними, с ограничением, что комплексные числа не поддерживают сравнение порядка. В пределах задействованных типов они сравниваются математически (алгоритмически) корректно без потери точности.616617 Значения «не число» (NaN) `float('NaN')` и `decimal.Decimal('NaN')` являются особыми. Любое упорядоченное сравнение числа со значением «не число» даёт ложь. Контринтуитивное следствие: значения «не число» не равны сами себе. Например, если `x = float('NaN')`, `3 < x`, `x < 3` и `x == x` – все ложны, а `x != x` истинно. Это поведение соответствует стандарту IEEE 754.618- Бинарные последовательности (экземпляры [`bytes`](https://python-all.ru/3.7/library/stdtypes.html#bytes) или [`bytearray`](https://python-all.ru/3.7/library/stdtypes.html#bytearray)) можно сравнивать как внутри своих типов, так и между ними. Они сравниваются лексикографически по числовым значениям своих элементов.619- Строки (экземпляры [`str`](https://python-all.ru/3.7/library/stdtypes.html#str)) сравниваются лексикографически по числовым кодовым точкам Unicode (результат встроенной функции [`ord()`](https://python-all.ru/3.7/library/functions.html#ord)) своих символов. [3](https://python-all.ru/3.7/reference/expressions.html#id19)620621 Строки и двоичные последовательности нельзя сравнивать напрямую.622- Последовательности (экземпляры [`tuple`](https://python-all.ru/3.7/library/stdtypes.html#tuple), [`list`](https://python-all.ru/3.7/library/stdtypes.html#list) или [`range`](https://python-all.ru/3.7/library/stdtypes.html#range)) можно сравнивать только внутри каждого из своих типов, с ограничением, что диапазоны не поддерживают сравнение порядка. Сравнение на равенство между этими типами даёт неравенство, а сравнение порядка между этими типами вызывает [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError).623624 Последовательности сравниваются лексикографически путём сравнения соответствующих элементов, при этом обеспечивается рефлексивность элементов.625626 При обеспечении рефлексивности элементов сравнение коллекций предполагает, что для элемента коллекции `x` `x == x` всегда истинно. Исходя из этого предположения, сначала сравнивается идентичность элементов, а сравнение элементов выполняется только для различных элементов. Такой подход даёт тот же результат, что и строгое сравнение элементов, если сравниваемые элементы рефлексивны. Для нерефлексивных элементов результат отличается от строгого сравнения элементов и может быть неожиданным: например, нерефлексивные значения not-a-number приводят к следующему поведению сравнения при использовании в списке:627628 ```python629 >>> nan = float('NaN')630 >>> nan is nan631 True632 >>> nan == nan633 False <-- the defined non-reflexive behavior of NaN634 >>> [nan] == [nan]635 True <-- list enforces reflexivity and tests identity first636 ```637638 Лексикографическое сравнение между встроенными коллекциями работает следующим образом:639640 - Чтобы две коллекции были равны при сравнении, они должны быть одного типа, иметь одинаковую длину, и каждая пара соответствующих элементов должна быть равной (например, `[1,2] == (1,2)` – ложь, так как типы разные).641 - Коллекции, поддерживающие сравнение порядка, упорядочиваются так же, как и их первые неравные элементы (например, `[1,2,x] <= [1,2,y]` имеет то же значение, что и `x <= y`). Если соответствующего элемента не существует, более короткая коллекция считается меньшей (например, `[1,2] < [1,2,3]` – истина).642- Отображения (экземпляры [`dict`](https://python-all.ru/3.7/library/stdtypes.html#dict)) равны тогда и только тогда, когда они содержат одинаковые пары *(ключ, значение)*. Сравнение ключей и значений на равенство обеспечивает рефлексивность.643644 Сравнения порядка (`<`, `>`, `<=` и `>=`) вызывают [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError).645- Множества (экземпляры [`set`](https://python-all.ru/3.7/library/stdtypes.html#set) или [`frozenset`](https://python-all.ru/3.7/library/stdtypes.html#frozenset)) можно сравнивать как внутри типа, так и между типами.646647 Они определяют операторы сравнения порядка как проверки на подмножество и надмножество. Эти отношения не задают полного порядка (например, два множества `{1,2}` и `{2,3}` не равны, не являются подмножеством друг друга и не являются надмножеством друг друга). Соответственно, множества не подходят в качестве аргументов для функций, зависящих от полного порядка (например, [`min()`](https://python-all.ru/3.7/library/functions.html#min), [`max()`](https://python-all.ru/3.7/library/functions.html#max) и [`sorted()`](https://python-all.ru/3.7/library/functions.html#sorted) дают неопределённые результаты, если на вход подаётся список множеств).648649 Сравнение множеств требует рефлексивности их элементов.650- У большинства других встроенных типов нет реализованных методов сравнения, поэтому они наследуют поведение сравнения по умолчанию.651652Пользовательские классы, которые настраивают своё поведение сравнения, должны по возможности следовать некоторым правилам согласованности:653654- Сравнение на равенство должно быть рефлексивным. Другими словами, идентичные объекты должны быть равны:655656 > `x is y` влечёт `x == y`657- Сравнение должно быть симметричным. Другими словами, следующие выражения должны давать одинаковый результат:658659 > `x == y` и `y == x`660 >661 > `x != y` и `y != x`662 >663 > `x < y` и `y > x`664 >665 > `x <= y` и `y >= x`666- Сравнение должно быть транзитивным. Следующие (неисчерпывающие) примеры это иллюстрируют:667668 > `x > y and y > z` влечёт `x > z`669 >670 > `x < y and y <= z` влечёт `x < z`671- Обратное сравнение должно давать логическое отрицание. Другими словами, следующие выражения должны давать одинаковый результат:672673 > `x == y` и `not x != y`674 >675 > `x < y` и `not x >= y` (для полного порядка)676 >677 > `x > y` и `not x <= y` (для полного порядка)678679 Последние два выражения применимы к полностью упорядоченным коллекциям (например, к последовательностям, но не к множествам или отображениям). См. также декоратор [`total_ordering()`](https://python-all.ru/3.7/library/functools.html#functools.total_ordering).680- Результат [`hash()`](https://python-all.ru/3.7/library/functions.html#hash) должен быть согласован с равенством. Объекты, которые равны, должны либо иметь одинаковое хеш-значение, либо быть помечены как нехешируемые.681682Python не требует соблюдения этих правил согласованности. Фактически, значения «не число» (NaN) являются примером их нарушения.683684### 6.10.2. Операции проверки принадлежности685686Операторы [`in`](https://python-all.ru/3.7/reference/expressions.html#in) и [`not in`](https://python-all.ru/3.7/reference/expressions.html#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)`.687688Для типов str и bytes `x in y` равно `True` тогда и только тогда, когда *x* является подстрокой *y*. Эквивалентная проверка: `y.find(x) != -1`. Пустые строки всегда считаются подстрокой любой другой строки, поэтому `"" in "abc"` вернёт `True`.689690Для пользовательских классов, которые определяют метод [`__contains__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__contains__), `x in y` возвращает `True`, если `y.__contains__(x)` возвращает истинное значение, и `False` в противном случае.691692Для пользовательских классов, которые не определяют [`__contains__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__contains__), но определяют [`__iter__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__iter__), `x in y` равно `True`, если при итерации по `y` встречается некоторое значение `z`, для которого выражение `x is z or x == z` истинно. Если во время итерации возникает исключение, это равносильно тому, что [`in`](https://python-all.ru/3.7/reference/expressions.html#in) вызвало это исключение.693694Наконец, используется протокол итерации старого стиля: если класс определяет [`__getitem__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__getitem__), `x in y` равно `True` тогда и только тогда, когда существует неотрицательный целочисленный индекс *i*, такой что `x is y[i] or x == y[i]`, и ни один меньший индекс не вызывает исключение [`IndexError`](https://python-all.ru/3.7/library/exceptions.html#IndexError). (Если возникает любое другое исключение, это равносильно тому, что [`in`](https://python-all.ru/3.7/reference/expressions.html#in) вызвало это исключение).695696Оператор [`not in`](https://python-all.ru/3.7/reference/expressions.html#not-in) определён так, что его истинностное значение противоположно [`in`](https://python-all.ru/3.7/reference/expressions.html#in).697698### 6.10.3. Сравнение идентичности699700Операторы [`is`](https://python-all.ru/3.7/reference/expressions.html#is) и [`is not`](https://python-all.ru/3.7/reference/expressions.html#is-not) проверяют идентичность объектов: `x is y` истинно тогда и только тогда, когда *x* и *y* являются одним и тем же объектом. Идентичность объекта определяется с помощью функции [`id()`](https://python-all.ru/3.7/library/functions.html#id). `x is not y` возвращает противоположное логическое значение. [4](https://python-all.ru/3.7/reference/expressions.html#id20)701702## 6.11. Логические операции703704```705706or_test ::= and_test | or_test "or" and_test707and_test ::= not_test | and_test "and" not_test708not_test ::= comparison | "not" not_test709```710711В контексте логических операций, а также когда выражения используются в операторах управления потоком, следующие значения интерпретируются как ложные: `False`, `None`, числовой ноль всех типов, а также пустые строки и контейнеры (включая строки, кортежи, списки, словари, множества и неизменяемые множества). Все остальные значения интерпретируются как истинные. Пользовательские объекты могут настраивать своё логическое значение, предоставив метод [`__bool__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__bool__).712713Оператор [`not`](https://python-all.ru/3.7/reference/expressions.html#not) возвращает `True`, если его аргумент ложен, и `False` в противном случае.714715Выражение `x and y` сначала вычисляет *x*; если *x* ложно, возвращается его значение; в противном случае вычисляется *y* и возвращается полученное значение.716717Выражение `x or y` сначала вычисляет *x*; если *x* истинно, возвращается его значение; в противном случае вычисляется *y* и возвращается полученное значение.718719Обратите внимание, что ни [`and`](https://python-all.ru/3.7/reference/expressions.html#and), ни [`or`](https://python-all.ru/3.7/reference/expressions.html#or) не ограничивают возвращаемое значение и тип до `False` и `True`, а возвращают последний вычисленный аргумент. Это иногда бывает полезно, например, если `s` – строка, которую нужно заменить значением по умолчанию, если она пуста, выражение `s or 'foo'` даёт нужное значение. Поскольку [`not`](https://python-all.ru/3.7/reference/expressions.html#not) должен создать новое значение, он возвращает логическое значение независимо от типа своего аргумента (например, `not 'foo'` даёт `False`, а не `''`).720721## 6.12. Условные выражения722723```724725conditional_expression ::= or_test ["if" or_test "else" expression]726expression ::= conditional_expression | lambda_expr727expression_nocond ::= or_test | lambda_expr_nocond728```729730Условные выражения (иногда называемые «тернарным оператором») имеют самый низкий приоритет среди всех операций Python.731732Выражение `x if C else y` сначала вычисляет условие *C*, а не *x*. Если *C* истинно, вычисляется *x* и возвращается его значение; в противном случае вычисляется *y* и возвращается его значение.733734См. [**PEP 308**](https://python-all.ru/3.7/reference/expressions.html) для получения дополнительных сведений об условных выражениях.735736## 6.13. Лямбда-выражения737738```739740lambda_expr ::= "lambda" [parameter_list] ":" expression741lambda_expr_nocond ::= "lambda" [parameter_list] ":" expression_nocond742```743744Лямбда-выражения (иногда называемые лямбда-формами) используются для создания анонимных функций. Выражение `lambda parameters: expression` возвращает объект функции. Этот безымянный объект ведёт себя как объект функции, определённый с помощью:745746```text747def <lambda>(parameters):748 return expression749```750751См. раздел [Определения функций](https://python-all.ru/3.7/reference/compound_stmts.html#function) о синтаксисе списков параметров. Обратите внимание, что функции, созданные с помощью лямбда-выражений, не могут содержать инструкции или аннотации.752753## 6.14. Списки выражений754755```756757expression_list ::= expression ("," expression)* [","]758starred_list ::= starred_item ("," starred_item)* [","]759starred_expression ::= expression | (starred_item ",")* [starred_item]760starred_item ::= expression | "*" or_expr761```762763За исключением случаев, когда список выражений является частью литерала списка или множества, список выражений, содержащий хотя бы одну запятую, образует кортеж. Длина кортежа равна количеству выражений в списке. Выражения вычисляются слева направо.764765Звёздочка `*` обозначает *распаковку итерируемого объекта*. Её операндом должен быть [итерируемый объект](https://python-all.ru/3.7/glossary.html#term-iterable). Итерируемый объект раскрывается в последовательность элементов, которые включаются в новый кортеж, список или множество в месте распаковки.766767Новое в версии 3.5: Распаковка итерируемых объектов в списках выражений, изначально предложенная в [**PEP 448**](https://python-all.ru/3.7/reference/expressions.html).768769Завершающая запятая требуется только для создания кортежа из одного элемента (т.н. *синглетон*); во всех остальных случаях она необязательна. Одиночное выражение без завершающей запятой не создаёт кортеж, а возвращает значение этого выражения. (Чтобы создать пустой кортеж, используйте пустую пару круглых скобок: `()`.)770771## 6.15. Порядок вычисления772773Python вычисляет выражения слева направо. Обратите внимание, что при вычислении присваивания сначала вычисляется правая часть, а затем левая.774775В следующих строках выражения будут вычисляться в арифметическом порядке их суффиксов:776777```python778expr1, expr2, expr3, expr4779(expr1, expr2, expr3, expr4)780{expr1: expr2, expr3: expr4}781expr1 + expr2 * (expr3 - expr4)782expr1(expr2, expr3, *expr4, **expr5)783expr3, expr4 = expr1, expr2784```785786## 6.16. Приоритет операторов787788В следующей таблице приведён приоритет операторов в Python от самого низкого (наименее связывающего) до самого высокого (наиболее связывающего). Операторы в одной ячейке имеют одинаковый приоритет. Если синтаксис не указан явно, операторы являются бинарными. Операторы в одной ячейке группируются слева направо (за исключением возведения в степень, которое группируется справа налево).789790Сравнения, проверки принадлежности и проверки тождественности имеют одинаковый приоритет и связываются слева направо, как описано в разделе [Сравнения](https://python-all.ru/3.7/reference/expressions.html#comparisons).791792| Оператор | Описание |793| --- | --- |794| [`lambda`](https://python-all.ru/3.7/reference/expressions.html#lambda) | Лямбда-выражение |795| [`if`](https://python-all.ru/3.7/reference/expressions.html#if-expr) – `else` | Условное выражение |796| [`or`](https://python-all.ru/3.7/reference/expressions.html#or) | Логическое ИЛИ |797| [`and`](https://python-all.ru/3.7/reference/expressions.html#and) | Логическое И |798| [`not`](https://python-all.ru/3.7/reference/expressions.html#not) `x` | Логическое НЕ |799| [`in`](https://python-all.ru/3.7/reference/expressions.html#in), [`not in`](https://python-all.ru/3.7/reference/expressions.html#not-in), [`is`](https://python-all.ru/3.7/reference/expressions.html#is), [`is not`](https://python-all.ru/3.7/reference/expressions.html#is-not), `<`, `<=`, `>`, `>=`, `!=`, `==` | Сравнения, включая проверки принадлежности и тождественности |800| `\|` | Побитовое ИЛИ |801| `^` | Побитовое исключающее ИЛИ |802| `&` | Побитовое И |803| `<<`, `>>` | Сдвиги |804| `+`, `-` | Сложение и вычитание |805| `*`, `@`, `/`, `//`, `%` | Умножение, матричное умножение, деление, целочисленное деление, остаток [5](https://python-all.ru/3.7/reference/expressions.html#id21) |806| `+x`, `-x`, `~x` | Унарный плюс, унарный минус, побитовое НЕ |807| `**` | Возведение в степень [6](https://python-all.ru/3.7/reference/expressions.html#id22) |808| [`await`](https://python-all.ru/3.7/reference/expressions.html#await) `x` | Выражение await |809| `x[index]`, `x[index:index]`, `x(arguments...)`, `x.attribute` | Индексация, срез, вызов, ссылка на атрибут |810| `(expressions...)`, `[expressions...]`, `{key: value...}`, `{expressions...}` | Связывание или выражение в скобках, список, словарь, множество |811812Сноски813814**[1](https://python-all.ru/3.7/reference/expressions.html#id9)**815816Хотя математически `abs(x%y) < abs(y)` истинно, для чисел с плавающей запятой оно может не выполняться численно из-за округления. Например, если предположить платформу, на которой число с плавающей запятой Python является числом двойной точности IEEE 754, то чтобы `-1e-100 % 1e100` имело тот же знак, что и `1e100`, вычисленный результат равен `-1e-100 + 1e100`, что численно в точности равно `1e100`. Функция [`math.fmod()`](https://python-all.ru/3.7/library/math.html#math.fmod) вместо этого возвращает результат, знак которого совпадает со знаком первого аргумента, поэтому в данном случае возвращает `-1e-100`. Какой подход более уместен, зависит от приложения.817818**[2](https://python-all.ru/3.7/reference/expressions.html#id10)**819820Если x очень близок к целому кратному y, возможно, что `x//y` будет на единицу больше `(x-x%y)//y` из-за округления. В таких случаях Python возвращает последний результат, чтобы `divmod(x,y)[0] * y + x % y` оставался очень близким к `x`.821822**[3](https://python-all.ru/3.7/reference/expressions.html#id12)**823824Стандарт Unicode различает *кодовые точки* (например, U+0041) и *абстрактные символы* (например, «LATIN CAPITAL LETTER A»). Хотя большинство абстрактных символов в Unicode представлены одной кодовой точкой, существует ряд абстрактных символов, которые могут быть представлены последовательностью из нескольких кодовых точек. Например, абстрактный символ «LATIN CAPITAL LETTER C WITH CEDILLA» может быть представлен как один *предварительно составленный символ* в позиции U+00C7 или как последовательность *базового символа* в позиции U+0043 (LATIN CAPITAL LETTER C), за которым следует *комбинируемый символ* в позиции U+0327 (COMBINING CEDILLA).825826Операторы сравнения строк сравнивают на уровне кодовых точек Unicode. Это может быть неинтуитивно для человека. Например, `"\u00C7" == "\u0043\u0327"` равно `False`, хотя обе строки представляют один и тот же абстрактный символ «LATIN CAPITAL LETTER C WITH CEDILLA».827828Для сравнения строк на уровне абстрактных символов (то есть интуитивно понятным способом) используется [`unicodedata.normalize()`](https://python-all.ru/3.7/library/unicodedata.html#unicodedata.normalize).829830**[4](https://python-all.ru/3.7/reference/expressions.html#id13)**831832Из-за автоматической сборки мусора, списков свободных объектов и динамической природы дескрипторов может наблюдаться, казалось бы, необычное поведение при определённых использованиях оператора [`is`](https://python-all.ru/3.7/reference/expressions.html#is), например, при сравнениях между методами экземпляров или константами. За дополнительной информацией обратитесь к их документации.833834**[5](https://python-all.ru/3.7/reference/expressions.html#id15)**835836Оператор `%` также используется для форматирования строк; для него действует тот же приоритет.837838**[6](https://python-all.ru/3.7/reference/expressions.html#id16)**839840Оператор возведения в степень `**` связывает менее тесно, чем арифметический или побитовый унарный оператор справа от него, то есть `2**-1` равно `0.5`.841