Spec-Zone.ru › Python 3.8

Выражения

В этой главе объясняется значение элементов выражений в 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.

Присвоение имени: Когда идентификатор, который текстово встречается в определении класса, начинается с двух или более символов подчёркивания и не заканчивается двумя или более символами подчёркивания, он считается приватным именем этого класса. Приватные имена преобразуются в более длинную форму до генерации кода для них. Преобразование вставляет имя класса, из которого удалены ведущие символы подчёркивания и вставлен один символ подчёркивания, перед именем. Например, идентификатор __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" expression_nocond [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.

Новое в версии 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

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

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

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

Новое в версии 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(type[, value[, traceback]])

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

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.

Для обработки завершения цикл событий должен определить функцию finalizer, которая принимает асинхронный итератор генератора и, предположительно, вызывает aclose() и выполняет корутину. Этот finalizer может быть зарегистрирован путём вызова sys.set_asyncgen_hooks(). При первой итерации по асинхронному итератору генератора будет сохранён зарегистрированный finalizer для вызова при завершении. Для примера реализации метода finalizer см. реализацию 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. Подписки

Подписка выбирает элемент последовательности (строка, кортеж или список) или объекта отображения (словарь):

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

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

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

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

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

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

Элементы строки — это символы. Символ — это не отдельный тип данных, а строка ровно из одного символа.

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.

Формальные параметры, использующие синтаксис *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.)

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

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

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

Унарный оператор - (минус) возвращает отрицание своего числового аргумента.

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

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

Во всех трех случаях, если аргумент не имеет правильного типа, генерируется исключение 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

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

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

Введено в версии 3.5.

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

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

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

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

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

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

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

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

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

Сдвиг вправо на 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

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

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

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

6.10. Сравнения

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

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

Сравнения возвращают булевы значения: True или False.

Сравнения могут быть сколь угодно объединены, например, 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 == y) основано на идентичности объектов. Следовательно, сравнение на равенство экземпляров с одинаковым идентификатором приводит к равенству, а сравнение на равенство экземпляров с разными идентификаторами приводит к неравенству. Мотивация такого поведения заключается в стремлении, чтобы все объекты были рефлексивными (т.е. 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 если при итерации по 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

Выражения присваивания (иногда также называемые «именованными выражениями» или «walrus») присваивают expression идентификатору, одновременно возвращая значение 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
expression_nocond      ::=  or_test | lambda_expr_nocond

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

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

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

6.14. Lambda

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

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

def <lambda>(parameters):
    return expression

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

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

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

Оператор

Описание

:=

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

lambda

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

if – else

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

or

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

and

Логическое И

not x

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

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

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

|

Битовое ИЛИ

^

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

&

Битовое И

<<, >>

Сдвиги

+, -

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

*, @, /, //, %

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

+x, -x, ~x

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

**

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

await x

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

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

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

(expressions...),

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

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

Примечания

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

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

6

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

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

Spec-Zone.ru

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