Spec-Zone.ru › Python 3.9

Выражения

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

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

name ::=  othername

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

6.1. Преобразования арифметических операций

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

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

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

6.2. Атомы

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

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

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

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

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

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

6.2.2. Литералы

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

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

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

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

6.2.3. Скобочные формы

Скобочная форма — это необязательный список выражений в круглых скобках:

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

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

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

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

6.2.4. Отображения для списков, множеств и словарей

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

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

Общие синтаксические элементы для генераторов:

comprehension ::=  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 выражения, он называется асинхронным генератором. Асинхронный генератор может приостановить выполнение функции корутины, в которой он появляется. См. также PEP 530.

New in version 3.6: Асинхронные генераторы.

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

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

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

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

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

6.2.6. Отображения множеств

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

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

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

Пустое множество нельзя создать с {}; этот литерал создаёт пустой словарь.

6.2.7. Отображения словарей

Отображение словаря — это, возможно, пустая последовательность пар «ключ/значение», заключённая в фигурные скобки:

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

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

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

Двойная звёздочка ** обозначает распаковку словаря. Его операнд должен быть отображением. Каждый элемент отображения добавляется в новый словарь. Позже значения заменяют значения, уже установленные предыдущими парами «ключ/значение» и предыдущими распаковками словарей.

New in version 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_expression ::=  "yield" [expression_list | "from" expression]

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

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

Выражения 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, где генератор снова приостанавливается, и значение выражения expression_list возвращается вызывающей программе метода __next__(). Если генератор завершается без возврата другого значения, возникает исключение StopIteration.

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

generator.send(value)

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

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

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

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

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

generator.close()

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

6.2.9.2. Примеры

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

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

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

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

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

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

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

В асинхронной функции генератора выражения 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. Методы итератора асинхронного генератора

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

coroutine agen.__anext__()

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

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

coroutine agen.asend(value)

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

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

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

coroutine agen.aclose()

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

6.3. Основные элементы

Основные элементы представляют собой наиболее тесно связанные операции языка. Их синтаксис:

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

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

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

attributeref ::=  primary "." identifier

Основной элемент должен быть объектом типа, поддерживающего ссылки на атрибуты, что большинство объектов делают. Затем от этого объекта требуется получить атрибут, имя которого является идентификатором. Это производство может быть настраиваемо путём переопределения метода __getattr__(). Если этот атрибут недоступен, возникает исключение AttributeError. В противном случае тип и значение созданного объекта определяются объектом. Несколько оценок одной и той же ссылки на атрибут могут давать разные объекты.

6.3.2. Подписки

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

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

Когда объект подписывается, интерпретатор вычисляет основной элемент и список выражений.

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

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

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

  1. Отображения. Если основной элемент является отображением, список выражений должен быть вычислен как объект, значение которого является одним из ключей отображения, и подписка выбирает значение в отображении, соответствующее этому ключу. Примером встроенного класса отображения является класс dict.
  2. Последовательности. Если основной элемент является последовательностью, список выражений должен быть вычислен как 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__(), что и обычная подписка) с ключом, построенным из списка срезов следующим образом. Если список срезов содержит по крайней мере одну запятую, ключ является кортежем, содержащим преобразование элементов среза; в противном случае преобразование единственного элемента среза является ключом. Преобразование элемента среза, являющегося выражением, — это само выражение. Преобразование правильного среза — это объект slice (см. раздел Стандартная иерархия типов), у которого атрибуты 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.

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

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

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

Если это —

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

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

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

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

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

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

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

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

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

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

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

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

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

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 не реализует этого оператора.

Новая функция с версии 3.5.

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

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

Оператор % (остаток от деления) возвращает остаток от деления первого аргумента на второй. Числовые аргументы сначала преобразуются к общему типу. Ноль в правом аргументе вызывает исключение 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__().

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

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

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

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

Эту операцию можно настроить, используя специальный метод __sub__().

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

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

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

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

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

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

6.9. Бинарные поразрядные операции

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

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

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

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

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

6.10. Сравнения

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

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

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

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

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

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

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

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

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

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

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

Стандартное сравнение по порядку (<, >, <=, и >= ) не предоставляется; попытка вызвать его вызовет TypeError. Мотивация для такого поведения — отсутствие подобного инварианта, как для равенства.

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

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

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

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

  • None и NotImplemented являются одиночными объектами. PEP 8 рекомендует для сравнения одиночных объектов всегда использовать is или is not, а не операторы равенства.
  • Бинарные последовательности (экземпляры bytes или bytearray) могут сравниваться внутри и между типами. Они сравниваются лексикографически с использованием числовых значений своих элементов.
  • Строки (экземпляры str) сравниваются лексикографически с использованием числовых кодов Unicode (результата встроенной функции ord()) их символов. 3

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

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

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

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

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

    Сравнения по порядку (<, >, <=, и >= ) вызывают TypeError.

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

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

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

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

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

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

    x is y подразумевает x == y

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

    x == y и y == x

    x != y и y != x

    x < y и y > x

    x <= y и y >= x

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

    x > y and y > z подразумевает x > z

    x < y and y <= z подразумевает x < z

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

    x == y и not x != y

    x < y и not x >= y (для полного упорядочения)

    x > y и not x <= y (для полного упорядочения)

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

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

Python не навязывает эти правила согласованности. Фактически, значения «не число» — пример нарушения этих правил.

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

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

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

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

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

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

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

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

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

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

Добавлено в версии 3.8: См. PEP 572 для получения более подробной информации о выражениях присваивания.

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

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

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

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

См. PEP 308 для получения более подробной информации об условных выражениях.

6.14. Лямбда-функции

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

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

def <lambda>(parameters):
    return expression

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

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

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

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

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

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

Запятая после последнего выражения нужна только для создания единственного кортежа (также известного как «кортеж-одиночка»); она необязательна во всех остальных случаях. Одно выражение без запятой не создаёт кортеж, а возвращает значение этого выражения. (Для создания пустого кортежа используйте пустую пару скобок: ().)

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

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

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

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

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

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

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

Оператор

Описание

(expressions...),

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

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

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

Индексация, срезы, вызов, обращение к атрибуту

await x

Выражение ожидания

**

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

+x, -x, ~x

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

*, @, /, //, %

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

+, -

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

<<, >>

Сдвиги

&

Побитовое И

^

Побитовое ИСКЛЮЧАЮЩЕЕ ИЛИ

|

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

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

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

not x

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

and

Логическое И

or

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

if – else

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

lambda

Выражение лямбда

:=

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

Примечания

1

Хотя abs(x%y) < abs(y) математически верно, для чисел с плавающей точкой это может не быть верно численно из-за округления. Например, и предполагая платформу, на которой Python float является числом двойной точности IEEE 754, чтобы -1e-100 % 1e100 имел тот же знак, что и 1e100, вычисленное значение равно -1e-100 + 1e100, что численно точно равно 1e100. Функция math.fmod() возвращает результат, знак которого совпадает со знаком первого аргумента, и поэтому возвращает -1e-100 в этом случае. Какой подход более уместен, зависит от приложения.

2

Если x очень близок к точному целочисленному кратному y, возможно, что x//y будет на единицу больше, чем (x-x%y)//y из-за округления. В таких случаях Python возвращает последнее значение, чтобы сохранить, что divmod(x,y)[0] * y + x % y очень близко к x.

3

Стандарт Unicode различает кодовые точки (например, U+0041) и абстрактные символы (например, «ЛАТИНСКАЯ ПРОПИСНАЯ БУКВА A»). Хотя большинство абстрактных символов в Unicode представлены только одной кодовой точкой, существует ряд абстрактных символов, которые могут быть представлены последовательностью из более чем одной кодовой точки. Например, абстрактный символ «ЛАТИНСКАЯ ПРОПИСНАЯ БУКВА C С ЦЕДИЛЛЕЙ» может быть представлен одним прекомпонованным символом в позиции кода U+00C7 или как последовательность из основного символа в позиции кода U+0043 (ЛАТИНСКАЯ ПРОПИСНАЯ БУКВА C), за которым следует комбинирующий символ в позиции кода U+0327 (КОМБИНИРУЮЩАЯ ЦЕДИЛЛЯ).

Операторы сравнения для строк сравнивают кодовые точки Unicode. Это может быть неинтуитивно для человека. Например, "\u00C7" == "\u0043\u0327" равно False, даже несмотря на то, что обе строки представляют один и тот же абстрактный символ «ЛАТИНСКАЯ ПРОПИСНАЯ БУКВА C С ЦЕДИЛЛЕЙ».

Чтобы сравнить строки на уровне абстрактных символов (то есть интуитивно для человека), используйте unicodedata.normalize().

4

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

5

Оператор возведения в степень ** связывается слабее, чем арифметический или побитовый унарный оператор справа, то есть 2**-1 равно 0.5.

6

Оператор % также используется для форматирования строк; применяется тот же приоритет.

© 2001–2022 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.9/reference/expressions.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API