Выражения
В этой главе объясняется значение элементов выражений в Python.
Примечания к синтаксису: В этой и следующих главах для описания синтаксиса, а не лексического анализа, используется расширенная нотация Бэкуса — Наура. Если (одна из альтернатив) синтаксического правила имеет вид
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.
6.2.1.1. Преобразование приватных имён
Если идентификатор, текстуально встречающийся в определении класса, начинается с двух или более символов подчёркивания и не заканчивается двумя или более символами подчёркивания, он считается приватным именем этого класса.
См. также
Точнее, перед генерацией кода приватные имена преобразуются в более длинную форму. Если длина преобразованного имени превышает 255 символов, может выполняться усечение, определяемое реализацией.
Преобразование не зависит от синтаксического контекста, в котором используется идентификатор, однако преобразованию подвергаются только следующие приватные идентификаторы:
-
Любое имя, используемое в качестве имени переменной, которой присваивается значение или которая считывается, а также любое имя доступного атрибута.
Однако атрибут
__name__вложенных функций, классов и псевдонимов типов не преобразуется. - Имя импортируемого модуля, например
__spamвimport __spam. Если модуль является частью пакета (то есть его имя содержит точку), имя не преобразуется; например,__fooвimport __foo.barне преобразуется. - Имя импортируемого элемента, например
__fвfrom spam import __f.
Правило преобразования определяется следующим образом:
- Имя класса, из которого удалены начальные символы подчёркивания и перед которым добавлен один начальный символ подчёркивания, вставляется перед идентификатором. Например, идентификатор
__spam, встречающийся в классе с именемFoo,_Fooили__Foo, преобразуется в_Foo__spam. - Если имя класса состоит только из символов подчёркивания, преобразование не выполняется. Например, идентификатор
__spam, встречающийся в классе с именем_или__, остаётся без изменений.
6.2.2. Литералы
Python поддерживает строковые и байтовые литералы, а также различные числовые литералы:
literal ::= stringliteral | bytesliteral
| integer | floatnumber | imagnumber
Вычисление литерала возвращает объект заданного типа (строку, байтовую последовательность, целое число, число с плавающей точкой, комплексное число) с заданным значением. Значение литералов с плавающей точкой и мнимой частью (комплексных чисел) может быть приближённым. Подробности см. в разделе Литералы.
Все литералы соответствуют неизменяемым типам данных, поэтому идентичность объекта менее важна, чем его значение. При нескольких вычислениях литералов с одинаковым значением (как одного и того же вхождения в тексте программы, так и разных вхождений) может быть получен один и тот же объект либо разные объекты с одинаковым значением.
6.2.3. Формы в скобках
Форма в скобках — это необязательный список выражений, заключённый в круглые скобки:
parenth_form ::= "(" [starred_expression] ")"
Выражение в скобках возвращает результат вычисления этого выражения: если список содержит хотя бы одну запятую, возвращается кортеж; в противном случае возвращается единственное выражение, составляющее этот список.
Пустая пара круглых скобок возвращает пустой объект-кортеж. Поскольку кортежи неизменяемы, применяются те же правила, что и для литералов (то есть два вхождения пустого кортежа могут возвращать как один и тот же объект, так и разные объекты).
Обратите внимание: кортежи образуются не круглыми скобками, а запятой. Исключением является пустой кортеж, для которого круглые скобки обязательны — разрешение использовать в выражениях непустое отсутствие содержимого без скобок привело бы к неоднозначностям и позволило бы незамеченными оставаться распространённым опечаткам.
6.2.4. Отображения списков, множеств и словарей
Для создания списка, множества или словаря Python предоставляет специальный синтаксис, называемый «отображениями». Каждый из этих контейнеров можно создать двумя способами:
- либо содержимое контейнера перечисляется явно,
- либо вычисляется с помощью набора инструкций цикла и фильтрации, называемого генератором.
Общие синтаксические элементы генераторов:
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 может использоваться для перебора асинхронного итератора. Генератор в функции async def может содержать часть for или async for после начального выражения, дополнительные части for или async for, а также выражения await.
Если генератор содержит части async for либо выражения await или другие асинхронные генераторы в любом месте, кроме выражения-итератора в самой левой части for, он называется асинхронным генератором. Асинхронный генератор может приостанавливать выполнение сопрограммы, в которой он находится. См. также PEP 530.
Добавлено в версии 3.6: Добавлены асинхронные генераторы.
Изменено в версии 3.8: yield и yield from запрещены в неявно вложенной области видимости.
Изменено в версии 3.11: Теперь асинхронные генераторы разрешены внутри генераторов в асинхронных функциях. Внешние генераторы неявно становятся асинхронными.
6.2.5. Отображения списков
Отображение списка — это, возможно, пустая последовательность выражений, заключённая в квадратные скобки:
list_display ::= "[" [flexible_expression_list | comprehension] "]"
Отображение списка возвращает новый объект-список, содержимое которого задаётся либо списком выражений, либо генератором. Если указана последовательность выражений, разделённых запятыми, они вычисляются слева направо и в том же порядке помещаются в объект-список. Если указан генератор, список формируется из элементов, полученных в результате его выполнения.
6.2.6. Отображения множеств
Отображение множества обозначается фигурными скобками и отличается от отображения словаря отсутствием двоеточий, разделяющих ключи и значения:
set_display ::= "{" (flexible_expression_list | comprehension) "}"
Отображение множества возвращает новый изменяемый объект-множество, содержимое которого задаётся последовательностью выражений либо генератором. Если указана последовательность выражений, разделённых запятыми, они вычисляются слева направо и добавляются в объект-множество. Если указан генератор, множество формируется из элементов, полученных в результате его выполнения.
Пустое множество нельзя создать с помощью {}; этот литерал создаёт пустой словарь.
6.2.7. Отображения словарей
Отображение словаря — это, возможно, пустая последовательность элементов словаря (пар «ключ/значение»), заключённая в фигурные скобки:
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
Отображение словаря возвращает новый объект-словарь.
Если указана последовательность элементов словаря, разделённых запятыми, они вычисляются слева направо и задают записи словаря: каждый объект-ключ используется в качестве ключа словаря для сохранения соответствующего значения. Это означает, что в списке элементов словаря можно указать один и тот же ключ несколько раз, а в итоговом словаре для этого ключа будет сохранено последнее указанное значение.
Две звёздочки ** обозначают распаковку словаря. Операнд должен быть отображением. Каждый элемент отображения добавляется в новый словарь. Более поздние значения заменяют значения, заданные ранее в элементах словаря и при предыдущих распаковках словарей.
Добавлено в версии 3.5: Добавлена распаковка в отображениях словарей, первоначально предложенная в PEP 448.
В отличие от генераторов списков и множеств, генератор словаря требует двух выражений, разделённых двоеточием, за которыми следуют обычные части «for» и «if». При выполнении генератора результирующие ключи и значения добавляются в новый словарь в порядке их получения.
Ограничения на типы значений ключей перечислены выше, в разделе Стандартная иерархия типов. (Кратко говоря, тип ключа должен поддерживать хеширование, что исключает все изменяемые объекты.) Совпадения дублирующихся ключей не обнаруживаются; для данного значения ключа сохраняется последнее значение (самое правое в отображении).
Изменено в версии 3.8: До Python 3.8 в генераторах словарей порядок вычисления ключа и значения не был чётко определён. В 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, оно называется асинхронным генераторным выражением. Асинхронное генераторное выражение возвращает новый объект асинхронного генератора, который является асинхронным итератором (см. раздел Асинхронные итераторы).
Добавлено в версии 3.6: Добавлены асинхронные генераторные выражения.
Изменено в версии 3.7: До Python 3.7 асинхронные генераторные выражения могли использоваться только в сопрограммах async def. Начиная с версии 3.7 асинхронные генераторные выражения могут использоваться в любой функции.
Изменено в версии 3.8: yield и yield from запрещены в неявно вложенной области видимости.
6.2.9. Выражения yield
yield_atom ::= "(" yield_expression ")"
yield_from ::= "yield" "from" expression
yield_expression ::= "yield" yield_list | yield_from
Выражение yield используется при определении функции генератора или функции асинхронного генератора и поэтому может использоваться только в теле определения функции. Использование выражения 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, где оно снова приостанавливается, возвращая значение yield_list вызывающему объекту генератора или None, если yield_list опущено. Под приостановкой подразумевается сохранение всего локального состояния, включая текущие привязки локальных переменных, указатель инструкции, внутренний стек вычислений и состояние любой обработки исключений. Когда выполнение возобновляется вызовом одного из методов генератора, функция может продолжить работу точно так, как если бы выражение yield было обычным внешним вызовом. Значение выражения yield после возобновления зависит от метода, возобновившего выполнение. Если используется __next__() (обычно через цикл for или встроенную функцию next()), результатом будет None. Если же используется send(), результатом будет значение, переданное этому методу.
Всё это делает функции-генераторы очень похожими на корутины: они выдают значения несколько раз, имеют более одной точки входа, а их выполнение может приостанавливаться. Единственное отличие состоит в том, что функция-генератор не может управлять тем, где продолжится выполнение после выдачи значения; управление всегда передаётся вызывающему объекту генератора.
Выражения yield разрешены в любом месте конструкции try. Если генератор не возобновлён до его завершения (при достижении нулевого счётчика ссылок или сборке мусора), вызывается метод close() итератора-генератора, что позволяет выполнить все ожидающие выполнения предложения finally.
При использовании yield from <expr> переданное выражение должно быть итерируемым объектом. Значения, полученные при переборе этого объекта, передаются напрямую вызывающему объекту методов текущего генератора. Любые значения, переданные с помощью send(), и любые исключения, переданные с помощью throw(), передаются базовому итератору, если у него есть соответствующие методы. В противном случае send() вызовет AttributeError или TypeError, а throw() немедленно вызовет переданное исключение.
Когда базовый итератор завершает работу, атрибут value возбужденного экземпляра StopIteration становится значением выражения yield. Его можно задать явно при возбуждении StopIteration или автоматически, если подчинённый итератор является генератором (путём возврата значения из подгенератора).
Изменено в версии 3.3: Добавлено yield from <expr> для передачи управления подчинённому итератору.
Скобки можно опустить, если выражение yield является единственным выражением в правой части оператора присваивания.
См. также
- PEP 255 — Простые генераторы
-
Предложение о добавлении генераторов и оператора
yieldв Python. - PEP 342 — Корутины с помощью усовершенствованных генераторов
-
Предложение по усовершенствованию API и синтаксиса генераторов, чтобы их можно было использовать как простые корутины.
- PEP 380 — Синтаксис передачи управления подгенератору
-
Предложение о введении синтаксиса
yield_from, упрощающего передачу управления подгенераторам. - PEP 525 — Асинхронные генераторы
-
Предложение, развивающее PEP 492 за счёт добавления возможностей генераторов функциям-корутинам.
6.2.9.1. Методы итератора-генератора
В этом подразделе описаны методы итератора-генератора. Их можно использовать для управления выполнением функции-генератора.
Обратите внимание: вызов любого из приведённых ниже методов генератора, когда генератор уже выполняется, вызывает исключение ValueError.
-
generator.__next__() -
Запускает выполнение функции-генератора или возобновляет его с места последнего выполненного выражения yield. Когда функция-генератор возобновляется методом
__next__(), текущее выражение yield всегда вычисляется какNone. Затем выполнение продолжается до следующего выражения yield, где генератор снова приостанавливается, а значениеyield_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 — экземпляром исключения. Если value не указан, для получения экземпляра вызывается конструктор type. Если указан traceback, он присваивается исключению; в противном случае существующий атрибут
__traceback__, сохранённый в value, может быть очищен.Изменено в версии 3.12: Вторая сигнатура (type[, value[, traceback]]) объявлена устаревшей и может быть удалена в будущей версии Python.
-
generator.close() -
Возбуждает исключение
GeneratorExitв точке, где функция-генератор была приостановлена (эквивалентно вызовуthrow(GeneratorExit)). Исключение возбуждается выражением yield, на котором генератор был приостановлен. Если функция-генератор перехватывает исключение и возвращает значение, это значение возвращается методом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: Синтаксис передачи управления подгенератору
6.2.9.3. Функции асинхронных генераторов
Наличие выражения yield в функции или методе, определённом с помощью async def, дополнительно определяет эту функцию как функцию асинхронного генератора.
При вызове функции асинхронного генератора она возвращает асинхронный итератор, называемый объектом асинхронного генератора. Этот объект управляет выполнением функции-генератора. Объект асинхронного генератора обычно используется в операторе async for внутри функции-корутины, так же как объект генератора используется в операторе for.
Вызов одного из методов асинхронного генератора возвращает объект ожидаемого объекта, и выполнение начинается при его ожидании. В этот момент выполнение продолжается до первого выражения yield, где оно снова приостанавливается, возвращая значение yield_list ожидающей корутине. Как и в случае с генератором, приостановка означает сохранение всего локального состояния, включая текущие привязки локальных переменных, указатель инструкции, внутренний стек вычислений и состояние любой обработки исключений. Когда выполнение возобновляется в результате ожидания следующего объекта, возвращённого методами асинхронного генератора, функция может продолжить работу точно так, как если бы выражение yield было обычным внешним вызовом. Значение выражения yield после возобновления зависит от метода, возобновившего выполнение. Если используется __anext__(), результатом будет None. Если же используется asend(), результатом будет значение, переданное этому методу.
Если асинхронный генератор неожиданно завершает работу досрочно из-за break, отмены задачи вызывающего объекта или других исключений, будет выполнен код асинхронной очистки генератора, который может возбудить исключения или обратиться к контекстным переменным в неожиданном контексте — возможно, после завершения задач, от которых он зависит, или во время остановки цикла событий, когда вызывается хук сборки мусора асинхронных генераторов. Чтобы этого не произошло, вызывающий объект должен явно закрыть асинхронный генератор, вызвав метод aclose(), чтобы завершить генератор и в конечном счёте отсоединить его от цикла событий.
В функции асинхронного генератора выражения yield разрешены в любом месте конструкции try. Однако если асинхронный генератор не возобновлён до его завершения (при достижении нулевого счётчика ссылок или сборке мусора), выражение yield внутри конструкции try может привести к тому, что ожидающие выполнения предложения finally не будут выполнены. В этом случае цикл событий или планировщик, выполняющий асинхронный генератор, должен вызвать метод aclose() итератора асинхронного генератора и выполнить полученный объект-корутину, чтобы обеспечить выполнение всех ожидающих предложений finally.
Для завершения генераторов при остановке цикла событий цикл событий должен определять функцию финализации, которая принимает итератор асинхронного генератора и, предположительно, вызывает aclose() и выполняет корутину. Эту функцию финализации можно зарегистрировать вызовом sys.set_asyncgen_hooks(). При первом переборе итератор асинхронного генератора сохраняет зарегистрированную функцию финализации, чтобы вызвать её при завершении. Пример реализации метода финализации см. в реализации asyncio.Loop.shutdown_asyncgens в файле Lib/asyncio/base_events.py.
Выражение yield from <expr> является синтаксической ошибкой при использовании в функции асинхронного генератора.
6.2.9.4. Методы итератора асинхронного генератора
В этом подразделе описаны методы итератора асинхронного генератора, используемые для управления выполнением функции-генератора.
-
async agen.__anext__() -
Возвращает ожидаемый объект, запуск которого начинает выполнение асинхронного генератора или возобновляет его с места последнего выполненного выражения yield. Когда функция асинхронного генератора возобновляется методом
__anext__(), текущее выражение yield всегда вычисляется какNoneв возвращённом ожидаемом объекте, запуск которого продолжит выполнение до следующего выражения yield. Значениеyield_listвыражения yield является значением исключенияStopIteration, возбуждённого завершающейся корутиной. Если асинхронный генератор завершает работу, не выдав другое значение, ожидаемый объект вместо этого возбуждает исключениеStopAsyncIteration, сообщая о завершении асинхронного перебора.Обычно этот метод неявно вызывается циклом
async for.
-
async agen.asend(value) -
Возвращает ожидаемый объект, запуск которого возобновляет выполнение асинхронного генератора. Как и метод
send()генератора, этот метод «отправляет» значение в функцию асинхронного генератора, а аргумент value становится результатом текущего выражения yield. Ожидаемый объект, возвращённый методомasend(), возвращает следующее значение, выданное генератором, в качестве значения возбужденного исключенияStopIterationили возбуждает исключениеStopAsyncIteration, если асинхронный генератор завершает работу, не выдав другое значение. При вызовеasend()для запуска асинхронного генератора в качестве аргумента необходимо передатьNone, поскольку выражения yield, которое могло бы получить значение, ещё нет.
-
async agen.athrow(value) - async agen.athrow(type[, value[, traceback]])
-
Возвращает ожидаемый объект, который возбуждает исключение типа
typeв точке, где асинхронный генератор был приостановлен, и возвращает следующее значение, выданное функцией-генератором, в качестве значения возбужденного исключенияStopIteration. Если асинхронный генератор завершает работу, не выдав другое значение, ожидаемый объект возбуждает исключениеStopAsyncIteration. Если функция-генератор не перехватывает переданное исключение или возбуждает другое исключение, то при запуске ожидаемого объекта это исключение передаётся вызывающему объекту ожидаемого объекта.Изменено в версии 3.12: Вторая сигнатура (type[, value[, traceback]]) объявлена устаревшей и может быть удалена в будущей версии Python.
-
async agen.aclose() -
Возвращает ожидаемый объект, который при запуске передаёт исключение
GeneratorExitфункции асинхронного генератора в точке, где она была приостановлена. Если функция асинхронного генератора после этого корректно завершает работу, уже закрыта или возбуждаетGeneratorExit(не перехватывая исключение), возвращённый ожидаемый объект возбудит исключениеStopIteration. Любые ожидаемые объекты, возвращённые последующими вызовами асинхронного генератора, возбудят исключениеStopAsyncIteration. Если асинхронный генератор выдаёт значение, ожидаемый объект возбуждает исключениеRuntimeError. Если асинхронный генератор возбуждает любое другое исключение, оно передаётся вызывающему объекту ожидаемого объекта. Если асинхронный генератор уже завершил работу из-за исключения или обычного завершения, последующие вызовыaclose()вернут ожидаемый объект, который ничего не делает.
6.3. Первичные выражения
Первичные выражения представляют собой операции языка с наиболее высоким приоритетом. Их синтаксис:
primary ::= atom | attributeref | subscription | slicing | call
6.3.1. Ссылки на атрибуты
Ссылка на атрибут — это первичное выражение, за которым следуют точка и имя:
attributeref ::= primary "." identifier
Первичное выражение должно вычисляться в объект типа, поддерживающего ссылки на атрибуты, а их поддерживает большинство объектов. Затем у объекта запрашивается атрибут с именем, заданным идентификатором. Тип и значение результата определяются объектом. При повторном вычислении одной и той же ссылки на атрибут могут возвращаться разные объекты.
Это поведение можно настроить, переопределив метод __getattribute__() или метод __getattr__(). Сначала вызывается метод __getattribute__(), который либо возвращает значение, либо вызывает исключение AttributeError, если атрибут недоступен.
Если возникает исключение AttributeError, а у объекта есть метод __getattr__(), этот метод вызывается в качестве резервного варианта.
6.3.2. Индексация
Индексация экземпляра класса-контейнера обычно выбирает элемент из контейнера. Индексация обобщённого класса обычно возвращает объект GenericAlias.
subscription ::= primary "[" flexible_expression_list "]"
При индексации объекта интерпретатор вычисляет первичное выражение и список выражений.
Первичное выражение должно вычисляться в объект, поддерживающий индексацию. Объект может поддерживать индексацию, определяя один или оба метода: __getitem__() и __class_getitem__(). При индексации первичного выражения результат вычисления списка выражений передаётся одному из этих методов. Подробнее о том, когда вызывается __class_getitem__, а не __getitem__, см. в разделе __class_getitem__ и __getitem__.
Если список выражений содержит хотя бы одну запятую или любое из выражений является распаковываемым, результатом его вычисления будет tuple, содержащий элементы списка выражений. В противном случае результатом вычисления списка выражений будет значение его единственного элемента.
Изменено в версии 3.11: Выражения в списке выражений могут быть распаковываемыми. См. PEP 646.
Для встроенных объектов есть два типа объектов, поддерживающих индексацию с помощью __getitem__():
- Отображения. Если первичное выражение — это отображение, список выражений должен вычисляться в объект, значение которого является одним из ключей отображения, а индексация выбирает значение отображения, соответствующее этому ключу. Пример встроенного класса отображения — класс
dict. - Последовательности. Если первичное выражение — это последовательность, список выражений должен вычисляться в
intилиslice(как описано в следующем разделе). Примеры встроенных классов последовательностей:str,listиtuple.
Формальный синтаксис не предусматривает специальной обработки отрицательных индексов в последовательностях. Однако встроенные последовательности предоставляют метод __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__(), что и при обычной индексации) ключом, построенным из списка срезов следующим образом. Если список срезов содержит хотя бы одну запятую, ключом будет кортеж, содержащий преобразованные элементы среза; в противном случае ключом будет результат преобразования единственного элемента среза. Если элемент среза является выражением, его преобразованием будет само это выражение. Преобразованием корректного среза будет объект-срез (см. раздел Стандартная иерархия типов), атрибуты start, stop и step которого содержат значения выражений, заданных в качестве нижней границы, верхней границы и шага соответственно; для отсутствующих выражений подставляется None.
6.3.4. Вызовы
Вызов применяет вызываемый объект (например, функцию) к, возможно, пустой последовательности аргументов:
call ::= primary "(" [argument_list [","] | comprehension] ")"
argument_list ::= positional_arguments ["," starred_and_keywords]
["," keywords_arguments]
| starred_and_keywords ["," keywords_arguments]
| keywords_arguments
positional_arguments ::= positional_item ("," positional_item)*
positional_item ::= assignment_expression | "*" expression
starred_and_keywords ::= ("*" expression | keyword_item)
("," "*" expression | "," keyword_item)*
keywords_arguments ::= (keyword_item | "**" expression)
("," keyword_item | "," "**" expression)*
keyword_item ::= identifier "=" expression
После позиционных и именованных аргументов может стоять необязательная завершающая запятая, не влияющая на семантику.
Первичное выражение должно вычисляться в вызываемый объект (вызываемыми являются пользовательские функции, встроенные функции, методы встроенных объектов, объекты классов, методы экземпляров классов и все объекты, имеющие метод __call__()). Все выражения-аргументы вычисляются до попытки вызова. Синтаксис списков формальных параметров описан в разделе Определения функций.
Если присутствуют именованные аргументы, сначала они преобразуются в позиционные следующим образом. Сначала для формальных параметров создаётся список незаполненных слотов. Если имеется N позиционных аргументов, они помещаются в первые N слотов. Затем для каждого именованного аргумента по идентификатору определяется соответствующий слот (если идентификатор совпадает с именем первого формального параметра, используется первый слот и так далее). Если слот уже заполнен, вызывается исключение TypeError. В противном случае аргумент помещается в слот и заполняет его (даже если выражение равно None, слот всё равно считается заполненным). После обработки всех аргументов незаполненные слоты заполняются соответствующими значениями по умолчанию из определения функции. (Значения по умолчанию вычисляются один раз, при определении функции; поэтому изменяемый объект, например список или словарь, используемый в качестве значения по умолчанию, будет общим для всех вызовов, в которых не указано значение соответствующего аргумента; этого обычно следует избегать.) Если остаются незаполненные слоты, для которых не задано значение по умолчанию, вызывается исключение TypeError. В противном случае список заполненных слотов используется в качестве списка аргументов вызова.
Особенность реализации CPython: Реализация может предоставлять встроенные функции, позиционные параметры которых не имеют имён, даже если в документации они «названы», и поэтому им нельзя передать аргументы по имени. В CPython это относится к функциям, реализованным на C и использующим PyArg_ParseTuple() для разбора аргументов.
Если позиционных аргументов больше, чем слотов формальных параметров, вызывается исключение TypeError, если только не задан формальный параметр с синтаксисом *identifier; в этом случае этот формальный параметр получает кортеж с лишними позиционными аргументами (или пустой кортеж, если лишних позиционных аргументов нет).
Если какой-либо именованный аргумент не соответствует имени формального параметра, вызывается исключение TypeError, если только не задан формальный параметр с синтаксисом **identifier; в этом случае этот формальный параметр получает словарь с лишними именованными аргументами (в котором имена аргументов используются как ключи, а значения аргументов — как соответствующие значения) или новый пустой словарь, если лишних именованных аргументов нет.
Если в вызове функции используется синтаксис *expression, выражение expression должно вычисляться в итерируемый объект. Элементы этих итерируемых объектов обрабатываются как дополнительные позиционные аргументы. Для вызова f(x1, x2, *y, x3, x4), если y вычисляется в последовательность y1, …, yM, это эквивалентно вызову с M+4 позиционными аргументами: x1, x2, y1, …, yM, x3, x4.
Из этого следует, что, хотя синтаксис *expression может встречаться после явных именованных аргументов, он обрабатывается до именованных аргументов (и любых аргументов **expression — см. ниже). Поэтому:
>>> def f(a, b): ... print(a, b) ... >>> f(b=1, *(2,)) 2 1 >>> f(a=1, *(2,)) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: f() got multiple values for keyword argument 'a' >>> f(1, *(2,)) 1 2
Одновременное использование именованных аргументов и синтаксиса *expression в одном вызове встречается редко, поэтому на практике такая неоднозначность возникает нечасто.
Если в вызове функции используется синтаксис **expression, выражение expression должно вычисляться в отображение, элементы которого обрабатываются как дополнительные именованные аргументы. Если параметру, соответствующему ключу, уже присвоено значение (явным именованным аргументом или при распаковке другого отображения), вызывается исключение TypeError.
При использовании **expression каждый ключ в этом отображении должен быть строкой. Каждое значение из отображения присваивается первому формальному параметру, которому можно передать аргумент по имени и имя которого совпадает с ключом. Ключ не обязан быть идентификатором Python (например, "max-temp °F" допустим, хотя он не совпадёт ни с одним формальным параметром, который можно объявить). Если соответствующий формальный параметр не найден, пара «ключ — значение» передаётся параметру **, если он есть; в противном случае вызывается исключение TypeError.
Формальные параметры с синтаксисом *identifier или **identifier нельзя использовать в качестве слотов для позиционных аргументов или имён именованных аргументов.
Изменено в версии 3.5: Вызовы функций принимают любое количество распаковок * и **; после распаковки итерируемого объекта могут следовать позиционные аргументы (*), а после распаковки словаря — именованные аргументы (**). Изначально предложено в PEP 448.
Вызов всегда возвращает некоторое значение, возможно, None, если только не возникает исключение. Способ вычисления этого значения зависит от типа вызываемого объекта.
Если это —
- пользовательская функция:
-
Выполняется блок кода функции, которому передаётся список аргументов. Первое, что делает блок кода, — связывает формальные параметры с аргументами; это описано в разделе Определения функций. Когда блок кода выполняет оператор
return, он задаёт возвращаемое значение вызова функции. Если выполнение доходит до конца блока кода без выполнения оператораreturn, возвращаемым значением будетNone. - встроенная функция или метод:
-
Результат зависит от интерпретатора; описания встроенных функций и методов см. в разделе Встроенные функции.
- объект класса:
-
Возвращается новый экземпляр этого класса.
- метод экземпляра класса:
-
Вызывается соответствующая пользовательская функция со списком аргументов, который на один элемент длиннее списка аргументов вызова: экземпляр становится первым аргументом.
- экземпляр класса:
-
Класс должен определять метод
__call__(); тогда результат будет таким же, как если бы был вызван этот метод.
6.4. Выражение await
Приостанавливает выполнение сопрограммы до завершения объекта ожидания. Может использоваться только внутри функции-сопрограммы.
await_expr ::= "await" primary
Добавлено в версии 3.5.
6.5. Оператор возведения в степень
Оператор возведения в степень имеет более высокий приоритет, чем унарные операторы слева от него, и более низкий приоритет, чем унарные операторы справа от него. Синтаксис:
power ::= (await_expr | primary) ["**" u_expr]
Таким образом, в последовательности операторов возведения в степень и унарных операторов без скобок операторы вычисляются справа налево (это не ограничивает порядок вычисления операндов): -1**2 даёт результат -1.
Семантика оператора возведения в степень совпадает с семантикой встроенной функции pow(), вызванной с двумя аргументами: он возводит левый аргумент в степень, заданную правым аргументом. Сначала числовые аргументы приводятся к общему типу, и результат имеет этот тип.
Для операндов типа int результат имеет тот же тип, что и операнды, если только второй аргумент не отрицательный; в этом случае все аргументы преобразуются к типу float, и результат также имеет тип float. Например, 10**2 возвращает 100, а 10**-2 возвращает 0.01.
Возведение 0.0 в отрицательную степень вызывает исключение ZeroDivisionError. Возведение отрицательного числа в дробную степень даёт число типа complex. (В более ранних версиях возникало исключение ValueError.)
Это поведение можно настроить с помощью специальных методов __pow__() и __rpow__().
6.6. Унарные арифметические и побитовые операции
Все унарные арифметические и побитовые операции имеют одинаковый приоритет:
u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr
Унарный оператор - (минус) возвращает противоположное значение числового аргумента; поведение можно переопределить специальным методом __neg__().
Унарный оператор + (плюс) возвращает числовой аргумент без изменений; поведение можно переопределить специальным методом __pos__().
Унарный оператор ~ (инверсия) возвращает побитовую инверсию целочисленного аргумента. Побитовая инверсия x определяется как -(x+1). Оператор применим только к целым числам или пользовательским объектам, переопределяющим специальный метод __invert__().
Во всех трёх случаях, если аргумент имеет неподходящий тип, вызывается исключение TypeError.
6.7. Бинарные арифметические операции
Бинарные арифметические операции имеют общепринятые уровни приоритета. Обратите внимание, что некоторые из этих операций применимы также к определённым нечисловым типам. Помимо оператора возведения в степень, есть только два уровня: один для операторов умножения и деления, другой — для операторов сложения и вычитания:
m_expr ::= u_expr | m_expr "*" u_expr | m_expr "@" m_expr |
m_expr "//" u_expr | m_expr "/" u_expr |
m_expr "%" u_expr
a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr
Оператор * (умножение) возвращает произведение аргументов. Аргументы должны быть либо оба числами, либо один аргумент должен быть целым числом, а другой — последовательностью. В первом случае числа приводятся к общему типу, а затем перемножаются. Во втором случае повторяется последовательность; при отрицательном множителе получается пустая последовательность.
Это поведение можно настроить с помощью специальных методов __mul__() и __rmul__().
Оператор @ (умножение матриц) предназначен для матричного умножения. Ни один встроенный тип Python не реализует этот оператор.
Это поведение можно настроить с помощью специальных методов __matmul__() и __rmatmul__().
Добавлено в версии 3.5.
Операторы / (деление) и // (деление нацело) возвращают частное от деления аргументов. Сначала числовые аргументы приводятся к общему типу. Деление целых чисел возвращает число с плавающей точкой, а деление целых чисел нацело возвращает целое число; результат соответствует математическому делению с применением к нему функции «пол» (floor). Деление на ноль вызывает исключение ZeroDivisionError.
Операцию деления можно настроить с помощью специальных методов __truediv__() и __rtruediv__(). Операцию деления нацело можно настроить с помощью специальных методов __floordiv__() и __rfloordiv__().
Оператор % (остаток от деления) возвращает остаток от деления первого аргумента на второй. Сначала числовые аргументы приводятся к общему типу. Если правый аргумент равен нулю, вызывается исключение ZeroDivisionError. Аргументы могут быть числами с плавающей точкой, например, 3.14%0.7 равно 0.34 (поскольку 3.14 равно 4*0.7 + 0.34). Оператор остатка от деления всегда возвращает результат со знаком второго операнда (или ноль); абсолютное значение результата строго меньше абсолютного значения второго операнда [1].
Операторы деления нацело и остатка от деления связаны следующим равенством: x == (x//y)*y + (x%y). Деление нацело и остаток от деления также связаны со встроенной функцией divmod(): divmod(x, y) == (x//y,
x%y). [2].
Помимо вычисления остатка от деления чисел, оператор % также переопределён для строк и выполняет форматирование строк в старом стиле (также известное как интерполяция). Синтаксис форматирования строк описан в Справочнике по библиотеке Python, в разделе Форматирование строк в стиле printf.
Операцию остатка от деления можно настроить с помощью специальных методов __mod__() и __rmod__().
Оператор деления нацело, оператор остатка от деления и функция divmod() не определены для комплексных чисел. Вместо этого при необходимости преобразуйте число в число с плавающей точкой с помощью функции abs().
Оператор + (сложение) возвращает сумму аргументов. Аргументы должны быть либо оба числами, либо последовательностями одного типа. В первом случае числа приводятся к общему типу и складываются. Во втором случае последовательности объединяются.
Это поведение можно настроить с помощью специальных методов __add__() и __radd__().
Оператор - (вычитание) возвращает разность аргументов. Сначала числовые аргументы приводятся к общему типу.
Это поведение можно настроить с помощью специальных методов __sub__() и __rsub__().
6.8. Операции сдвига
Операции сдвига имеют более низкий приоритет, чем арифметические операции:
shift_expr ::= a_expr | shift_expr ("<<" | ">>") a_expr
Эти операторы принимают целые числа в качестве аргументов. Они сдвигают первый аргумент влево или вправо на указанное вторым аргументом количество битов.
Операцию сдвига влево можно настроить с помощью специальных методов __lshift__() и __rlshift__(). Операцию сдвига вправо можно настроить с помощью специальных методов __rshift__() и __rrshift__().
Сдвиг вправо на n битов определяется как деление на pow(2,n) нацело. Сдвиг влево на n битов определяется как умножение на pow(2,n).
6.9. Двоичные побитовые операции
Каждая из трёх побитовых операций имеет свой уровень приоритета:
and_expr ::= shift_expr | and_expr "&" shift_expr xor_expr ::= and_expr | xor_expr "^" and_expr or_expr ::= xor_expr | or_expr "|" xor_expr
Оператор & выполняет побитовое И над своими аргументами, которые должны быть целыми числами, либо один из них должен быть пользовательским объектом, переопределяющим специальные методы __and__() или __rand__().
Оператор ^ выполняет побитовое исключающее ИЛИ над своими аргументами, которые должны быть целыми числами, либо один из них должен быть пользовательским объектом, переопределяющим специальные методы __xor__() или __rxor__().
Оператор | выполняет побитовое включающее ИЛИ над своими аргументами, которые должны быть целыми числами, либо один из них должен быть пользовательским объектом, переопределяющим специальные методы __or__() или __ror__().
6.10. Сравнения
В отличие от C, все операции сравнения в Python имеют одинаковый приоритет, который ниже приоритета любых арифметических операций, операций сдвига или побитовых операций. Кроме того, в отличие от C, выражения вида a < b < c интерпретируются так, как принято в математике:
comparison ::= or_expr (comp_operator or_expr)*
comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="
| "is" ["not"] | ["not"] "in"
Сравнения возвращают логические значения: True или False. Пользовательские методы расширенного сравнения могут возвращать нелогические значения. В этом случае Python вызовет для такого значения bool() в логическом контексте.
Сравнения можно объединять в цепочки произвольной длины, например, x < y <= z эквивалентно x < y and y <= z, за исключением того, что y вычисляется только один раз (однако в обоих случаях z вообще не вычисляется, если x < y оказывается ложным).
Формально, если a, b, c, …, y, z — выражения, а op1, op2, …, opN — операторы сравнения, то a op1 b op2 c ... y opN z эквивалентно a op1 b and b op2 c and ... y opN z, за исключением того, что каждое выражение вычисляется не более одного раза.
Обратите внимание: a op1 b op2 c не подразумевает сравнения какого-либо рода между a и c, поэтому, например, x < y > z вполне допустимо (хотя, возможно, и не слишком красиво).
6.10.1. Сравнения значений
Операторы <, >, ==, >=, <= и != сравнивают значения двух объектов. Объекты не обязаны иметь одинаковый тип.
В главе Объекты, значения и типы говорится, что у объектов есть значение (в дополнение к типу и идентичности). В Python понятие значения объекта довольно абстрактно: например, для объекта не существует канонического способа доступа к его значению. Также нет требования, чтобы значение объекта формировалось определённым образом, например состояло из всех его атрибутов данных. Операторы сравнения реализуют определённое представление о том, что является значением объекта. Их можно считать косвенным определением значения объекта посредством реализации сравнения.
Поскольку все типы являются (прямыми или косвенными) подтипами object, они наследуют стандартное поведение сравнения от object. Типы могут настраивать поведение сравнения, реализуя методы расширенного сравнения, такие как __lt__(), описанный в разделе Основная настройка.
Стандартное поведение при сравнении на равенство (== и !=) основано на идентичности объектов. Поэтому сравнение на равенство экземпляров с одинаковой идентичностью даёт равенство, а сравнение экземпляров с разной идентичностью — неравенство. Одно из обоснований такого поведения по умолчанию — стремление к тому, чтобы все объекты были рефлексивными (то есть из x is y следует x == y).
Стандартное сравнение на упорядоченность (<, >, <= и >=) не предоставляется; попытка его выполнить приводит к исключению TypeError. Такое поведение по умолчанию обусловлено отсутствием инварианта, аналогичного инварианту для равенства.
Стандартное поведение сравнения на равенство, при котором экземпляры с разной идентичностью всегда неравны, может противоречить потребностям типов, для которых имеет смысл определение значения объекта и сравнение на равенство по значению. Такие типы должны настраивать поведение сравнения; некоторые встроенные типы уже это делают.
В следующем списке описано поведение сравнения для наиболее важных встроенных типов.
-
Числа встроенных числовых типов (Числовые типы — 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 == xx != yиy != xx < yиy > xx <= yиy >= x -
Сравнение должно быть транзитивным. Это иллюстрируют следующие (неисчерпывающие) примеры:
x > y and y > zвлечётx > zx < y and y <= zвлечётx < z -
Обратное сравнение должно давать логическое отрицание. Иными словами, следующие выражения должны давать одинаковый результат:
x == yиnot x != yx < yиnot x >= y(для полного порядка)x > yиnot x <= y(для полного порядка)Последние два выражения применимы к коллекциям с полным порядком (например, к последовательностям, но не к множествам или отображениям). См. также декоратор
total_ordering(). - Результат
hash()должен быть согласован с равенством. Равные объекты должны иметь одинаковое хеш-значение либо быть помечены как нехешируемые.
Python не обеспечивает соблюдение этих правил согласованности. Значения «не число» как раз являются примером их нарушения.
6.10.2. Операции проверки принадлежности
Операторы in и not in проверяют принадлежность. Выражение x in
s возвращает True, если x является элементом s, и False в противном случае. x not in s возвращает логическое отрицание x in s. Эта возможность поддерживается всеми встроенными последовательностями и типами множеств, а также словарями, для которых in проверяет, содержит ли словарь заданный ключ. Для таких типов контейнеров, как list, tuple, set, frozenset, dict или collections.deque, выражение x in y эквивалентно any(x is e or x == e for e in y).
Для типов 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, None, числовой ноль любого типа, а также пустые строки и контейнеры (включая строки, кортежи, списки, словари, множества и неизменяемые множества). Все остальные значения интерпретируются как истинные. Пользовательские объекты могут настраивать своё логическое значение, предоставляя метод __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)
Выражения присваивания необходимо заключать в скобки, если они используются как выражения-операторы, а также в качестве подвыражений в срезах, условных выражениях, лямбда-выражениях, выражениях ключевых аргументов и выражениях if в генераторах, а также в операторах assert, with и assignment. Во всех остальных местах, где их можно использовать, скобки не требуются, в том числе в операторах if и while.
Добавлено в версии 3.8: Подробности о выражениях присваивания см. в PEP 572.
6.13. Условные выражения
conditional_expression ::= or_test ["if" or_test "else" expression] expression ::= conditional_expression | lambda_expr
Условные выражения (иногда называемые «тернарным оператором») имеют самый низкий приоритет среди всех операций 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. Списки выражений
starred_expression ::= ["*"] or_expr
flexible_expression ::= assignment_expression | starred_expression
flexible_expression_list ::= flexible_expression ("," flexible_expression)* [","]
starred_expression_list ::= starred_expression ("," starred_expression)* [","]
expression_list ::= expression ("," expression)* [","]
yield_list ::= expression_list | starred_expression "," [starred_expression_list]
Если список выражений, содержащий хотя бы одну запятую, не является частью отображения списка или множества, он возвращает кортеж. Длина кортежа равна числу выражений в списке. Выражения вычисляются слева направо.
Звёздочка * обозначает распаковку итерируемого объекта. Её операнд должен быть итерируемым объектом. Итерируемый объект раскрывается в последовательность элементов, которые включаются в новый кортеж, список или множество в месте распаковки.
Добавлено в версии 3.5: Распаковка итерируемых объектов в списках выражений, первоначально предложенная в PEP 448.
Добавлено в версии 3.11: Любой элемент списка выражений может иметь префикс-звёздочку. См. PEP 646.
Завершающая запятая нужна только для создания кортежа из одного элемента, например 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 — от наивысшего (наиболее сильное связывание) до наинизшего (наименее сильное связывание). Операторы в одной ячейке имеют одинаковый приоритет. Если синтаксис явно не указан, операторы являются бинарными. Операторы с одинаковым приоритетом группируются слева направо (за исключением возведения в степень и условных выражений, которые группируются справа налево).
Обратите внимание, что сравнения, проверки вхождения и проверки идентичности имеют одинаковый приоритет и поддерживают цепочки слева направо, как описано в разделе Сравнения.
Оператор | Описание |
|---|---|
|
| Связывание или выражение в скобках, отображение списка, отображение словаря, отображение множества |
| Индексация, срез, вызов, ссылка на атрибут |
Выражение await | |
| Возведение в степень [5] |
| Унарный плюс, унарный минус, побитовое НЕ |
| Умножение, умножение матриц, деление, целочисленное деление, остаток от деления [6] |
| Сложение и вычитание |
| Сдвиги |
| Побитовое И |
| Побитовое исключающее ИЛИ |
| Побитовое ИЛИ |
Сравнения, включая проверки вхождения и проверки идентичности | |
Логическое НЕ | |
Логическое И | |
Логическое ИЛИ | |
| Условное выражение |
Лямбда-выражение | |
| Выражение присваивания |
Сноски
© 2001–2025 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/reference/expressions.html