Выражения
В этой главе объясняется значение элементов выражений в Python.
Примечания по синтаксису: В этой и последующих главах будет использоваться расширенная форма БНФ для описания синтаксиса, а не лексического анализа. Когда (один вариант) правило синтаксиса имеет вид
name ::= othername
и семантика не приведена, семантика этой формы name такая же, как и для othername.
6.1. Арифметические преобразования
Когда в описании арифметического оператора ниже используется фраза «числовые аргументы преобразуются к общему типу», это означает, что реализация оператора для встроенных типов работает следующим образом:
- Если один из аргументов — комплексное число, другой преобразуется к комплексному;
- в противном случае, если один из аргументов — число с плавающей точкой, другой преобразуется в число с плавающей точкой;
- в противном случае оба должны быть целыми числами и преобразование не требуется.
Некоторые дополнительные правила применяются для определенных операторов (например, строка в качестве левого аргумента оператора «%»). Расширения должны определять собственное поведение преобразования.
6.2. Атомы
Атомы являются наиболее базовыми элементами выражений. Простейшие атомы — это идентификаторы или литералы. Формы, заключённые в скобки, квадратные скобки или фигурные скобки, также синтаксически классифицируются как атомы. Синтаксис атомов:
atom ::= identifier | literal | enclosure
enclosure ::= parenth_form | list_display | dict_display | set_display
| generator_expression | yield_atom
6.2.1. Идентификаторы (имена)
Идентификатор, встречающийся как атом, является именем. См. раздел Идентификаторы и ключевые слова для лексического определения и раздел Именование и привязка для документации именования и привязки.
Когда имя привязано к объекту, вычисление атома возвращает этот объект. Когда имя не привязано, попытка его вычисления вызывает исключение NameError.
6.2.1.1. Изменение имени для приватных членов
Когда идентификатор, который текстово встречается в определении класса, начинается с двух или более символов подчёркивания и не заканчивается двумя или более символами подчёркивания, он считается приватным именем этого класса.
См. также
Раздел определения классов.
Более точно, приватные имена преобразуются в более длинную форму перед генерацией кода для них. Если преобразованное имя длиннее 255 символов, может произойти реализационно-зависимое усечение.
Преобразование независимо от синтаксического контекста, в котором используется идентификатор, но только следующие приватные идентификаторы изменяются:
-
Любое имя, используемое в качестве имени переменной, которой присваивается или считывается значение, или любое имя атрибута, к которому осуществляется доступ.
Атрибут
__name__вложенных функций, классов и псевдонимов типов, однако, не изменяется. - Имя импортированных модулей, например,
__spamвimport __spam. Если модуль является частью пакета (т.е., его имя содержит точку), имя не изменяется, например, имя__fooвimport __foo.barне изменяется. - Имя импортированного члена, например,
__fвfrom spam import __f.
Правило преобразования определяется следующим образом:
- Имя класса, с удаленными ведущими подчёркиваниями и вставленным одним ведущим подчёркиванием, вставляется перед идентификатором, например, идентификатор
__spam, встречающийся в классе с именемFoo,_Fooили__Foo, преобразуется в_Foo__spam. - Если имя класса состоит только из подчёркиваний, преобразование является тождественным, например, идентификатор
__spam, встречающийся в классе с именем_или__, остаётся неизменным.
6.2.2. Литералы
Python поддерживает строковые и байтовые литералы, а также различные числовые литералы:
literal ::= stringliteral | bytesliteral
| integer | floatnumber | imagnumber
Вычисление литерала возвращает объект заданного типа (строка, байты, целое число, число с плавающей точкой, комплексное число) с заданным значением. Значение может быть приближённым в случае литералов с плавающей точкой и мнимой (комплексной) частью. Подробности см. в разделе Литералы.
Все литералы соответствуют неизменяемым типам данных, и поэтому идентификатор объекта менее важен, чем его значение. Несколько вычислений литералов с одинаковым значением (либо один и тот же экземпляр в тексте программы, либо разные экземпляры) могут получить один и тот же объект или разные объекты с одинаковым значением.
6.2.3. Формы в скобках
Форма в скобках — это необязательный список выражений, заключённый в круглые скобки:
parenth_form ::= "(" [starred_expression] ")"
Список выражений в скобках возвращает то, что возвращает этот список выражений: если список содержит по крайней мере одну запятую, он возвращает кортеж; в противном случае он возвращает единственное выражение, из которого состоит список выражений.
Пустая пара круглых скобок возвращает пустой кортеж. Поскольку кортежи неизменяемы, применяются те же правила, что и для литералов (т.е., два появления пустого кортежа могут или не могут возвращать один и тот же объект).
Обратите внимание, что кортежи не образуются скобками, а с помощью запятой. Исключением является пустой кортеж, для которого скобки необходимы — отсутствие скобок при «ничего» в выражениях вызвало бы неоднозначность и позволило бы некоторым распространённым опечаткам остаться незамеченными.
6.2.4. Представления списков, множеств и словарей
Для создания списка, множества или словаря Python предоставляет специальный синтаксис, называемый «представлениями», каждый из которых имеет два варианта:
- либо содержимое контейнера перечисляется явно, или
- они вычисляются с помощью набора инструкций цикла и фильтрации, называемых генератором.
Общие элементы синтаксиса для генераторов:
comprehension ::= assignment_expression comp_for comp_for ::= ["async"] "for" target_list "in" or_test [comp_iter] comp_iter ::= comp_for | comp_if comp_if ::= "if" or_test [comp_iter]
Генератор состоит из одного выражения, за которым следует по крайней мере один for и ноль или более for или if предложений. В этом случае элементами нового контейнера будут те, которые были бы получены, если бы каждое из for или if предложений рассматривалось как блок, вложенный слева направо, и выражение вычислялось для получения элемента каждый раз, когда достигался самый внутренний блок.
Однако, кроме выражения итерируемого в крайнем левом for предложении, генератор выполняется в отдельном неявном вложенном пространстве имён. Это гарантирует, что имена, присвоенные в целевом списке, не «вытекают» во внешнее пространство имён.
Выражение итерируемого в крайнем левом for предложении вычисляется непосредственно во внешнем пространстве имён и затем передаётся в неявное вложенное пространство имён в качестве аргумента. Последующие for предложения и любой фильтр в крайнем левом for предложении не могут быть вычислены во внешнем пространстве имён, так как они могут зависеть от значений, полученных из левого итерируемого выражения. Например: [x*y for x in range(10) for y in range(x, x+10)].
Чтобы гарантировать, что генератор всегда создаёт контейнер соответствующего типа, yield и yield from выражения запрещены во вложенном пространстве имён.
С Python 3.6 в функции async def может использоваться async for предложение для итерации по асинхронному итератору. Генератор в функции async def может состоять из for или async for предложения, следующих за ведущим выражением, может содержать дополнительные for или async for предложения и также может использовать await выражения.
Если генератор содержит async for предложения или если он содержит await выражения или другие асинхронные генераторы в любом месте, кроме выражения итерируемого в крайнем левом for предложении, он называется асинхронным генератором. Асинхронный генератор может приостановить выполнение функции корутины, в которой он появляется. См. также PEP 530.
Добавлено в версии 3.6: Асинхронные генераторы.
Изменено в версии 3.8: yield и yield from запрещены во вложенном пространстве имён.
Изменено в версии 3.11: Асинхронные генераторы теперь разрешены внутри генераторов в асинхронных функциях. Внешние генераторы неявно становятся асинхронными.
6.2.5. Представления списков
Представление списка — это, возможно, пустая последовательность выражений, заключённая в квадратные скобки:
list_display ::= "[" [flexible_expression_list | comprehension] "]"
Представление списка возвращает новый объект списка, содержимое которого задаётся либо списком выражений, либо генератором. Когда предоставляется список выражений, разделённых запятыми, его элементы вычисляются слева направо и помещаются в объект списка в этом порядке. Когда предоставляется генератор, список создаётся из элементов, полученных из генератора.
6.2.6. Представления множеств
Представление множества обозначается фигурными скобками и отличается от представлений словарей отсутствием двоеточий, разделяющих ключи и значения:
set_display ::= "{" (flexible_expression_list | comprehension) "}"
Представление множества возвращает новый изменяемый объект множества, содержимое которого задаётся либо последовательностью выражений, либо генератором. Когда предоставляется список выражений, разделённых запятыми, его элементы вычисляются слева направо и добавляются в объект множества. Когда предоставляется генератор, множество создаётся из элементов, полученных из генератора.
Пустое множество не может быть создано с помощью {}; этот литерал создаёт пустой словарь.
6.2.7. Отображения словарей
Отображение словаря — это, возможно, пустая последовательность элементов словаря (пар «ключ/значение»), заключённых в фигурные скобки:
dict_display ::= "{" [dict_item_list | dict_comprehension] "}"
dict_item_list ::= dict_item ("," dict_item)* [","]
dict_item ::= expression ":" expression | "**" or_expr
dict_comprehension ::= expression ":" expression comp_for
Отображение словаря возвращает новый объект словаря.
Если задана последовательность элементов словаря, разделённых запятыми, они оцениваются слева направо для определения записей словаря: каждый объект ключа используется в качестве ключа в словаре для хранения соответствующего значения. Это означает, что вы можете указывать один и тот же ключ несколько раз в списке элементов словаря, и конечное значение словаря для этого ключа будет последним заданным.
Двойная звёздочка ** обозначает распаковку словаря. Его операнд должен быть отображением. Каждый элемент отображения добавляется в новый словарь. Более поздние значения заменяют значения, уже установленные предыдущими элементами словаря и предыдущими распаковками словарей.
Добавлено в версии 3.5: Распаковка в отображения словарей, изначально предложенная PEP 448.
Выражение со словарем, в отличие от выражений со списками и множествами, требует двух выражений, разделённых двоеточием, за которыми следуют обычные предложения «for» и «if». При выполнении выражения результирующие элементы ключа и значения вставляются в новый словарь в порядке их создания.
Ограничения на типы значений ключей перечислены ранее в разделе Стандартная иерархия типов. (В качестве резюме, тип ключа должен быть хешируемым, что исключает все изменяемые объекты.) Коллизии между дублирующими ключами не обнаруживаются; последнее значение (текстово справа в отображении) хранимое для данного значения ключа преобладает.
Изменено в версии 3.8: Прежде чем Python 3.8, порядок оценки ключа и значения в выражениях со словарем не был определён. В CPython значение оценивалось до ключа. Начиная с 3.8, ключ оценивается до значения, как предложено PEP 572.
6.2.8. Выражения генераторов
Выражение генератора — это компактная нотация генератора в скобках:
generator_expression ::= "(" expression comp_for ")"
Выражение генератора возвращает новый объект генератора. Его синтаксис такой же, как и для выражений, за исключением того, что он заключён в скобки вместо квадратных скобок или фигурных скобок.
Переменные, используемые в выражении генератора, оцениваются лениво, когда для объекта генератора вызывается метод __next__() (так же, как и для обычных генераторов). Однако выражение итерируемого объекта в самом левом for предложении оценивается немедленно, так что ошибка, сгенерированная им, будет выдаваться в момент определения выражения генератора, а не в момент получения первого значения. Последующие for предложения и любое условие фильтрации в самом левом for предложении не могут быть оценены в окружающем пространстве, так как они могут зависеть от значений, полученных от самого левого итерируемого объекта. Например: (x*y for x in range(10) for y in range(x, x+10)).
Скобки могут быть опущены при вызовах с одним аргументом. Подробности см. в разделе Вызовы.
Чтобы избежать вмешательства в ожидаемую работу выражения генератора, yield и yield from выражения запрещены в неявном определённом генераторе.
Если выражение генератора содержит либо async for предложения, либо await выражения, оно называется выражением асинхронного генератора. Выражение асинхронного генератора возвращает новый объект асинхронного генератора, который является асинхронным итератором (см. Асинхронные итераторы).
Добавлено в версии 3.6: Были введены выражения асинхронных генераторов.
Изменено в версии 3.7: Перед Python 3.7 выражения асинхронных генераторов могли появляться только в async def корутинах. Начиная с 3.7, любое функция может использовать выражения асинхронных генераторов.
Изменено в версии 3.8: yield и yield from запрещены во вложенном пространстве имён.
6.2.9. Выражения yield
yield_atom ::= "(" yield_expression ")"
yield_from ::= "yield" "from" expression
yield_expression ::= "yield" yield_list | yield_from
Выражение yield используется при определении функции-генератора или функции-асинхронного генератора, и поэтому может использоваться только в теле определения функции. Использование выражения yield в теле функции делает эту функцию функцией-генератором, а использование его в теле функции-корутины делает эту корутинную функцию функцией-асинхронного генератора. Например:
def gen(): # defines a generator function
yield 123
async def agen(): # defines an asynchronous generator function
yield 123
Из-за побочных эффектов на область видимости, yield выражения не допускаются в качестве части неявно определённых областей видимости, используемых для реализации списковых и генераторских выражений.
Изменено в версии 3.8: Выражения yield запрещены в неявно вложенных областях видимости, используемых для реализации списковых и генераторских выражений.
Функции-генераторы описаны ниже, а функции-асинхронные генераторы описаны отдельно в разделе Функции-асинхронные генераторы.
Когда вызывается функция-генератор, она возвращает итератор, известный как генератор. Этот генератор затем управляет выполнением функции-генератора. Выполнение начинается, когда вызывается один из методов генератора. В этот момент выполнение переходит к первому выражению yield, где оно приостанавливается снова, возвращая значение yield_list вызывающей стороне генератора или None если yield_list опущено. Под приостановкой мы подразумеваем, что весь локальный состояние сохраняется, включая текущие связи локальных переменных, указатель инструкции, внутренний стек вычислений и состояние обработки исключений. Когда выполнение возобновляется путём вызова одного из методов генератора, функция может продолжить точно так же, как если бы выражение yield было просто другим внешним вызовом. Значение выражения yield после возобновления зависит от метода, который возобновил выполнение. Если используется __next__() (обычно через for или встроенную функцию next()), то результатом является None. В противном случае, если используется send(), результат будет значением, переданным в этот метод.
Всё это делает функции-генераторы весьма похожими на корутины; они возвращают значения многократно, у них больше одной точки входа, и их выполнение может приостанавливаться. Единственное отличие состоит в том, что функция-генератор не может управлять тем, где выполнение должно продолжиться после возврата значения; управление всегда передаётся вызывающей стороне генератора.
Выражения yield разрешены где угодно в конструкции try. Если генератор не возобновляется до его финализации (до достижения нулевого счётчика ссылок или до сборки мусора), вызывается метод генератор-итератора close(), что позволяет выполнить все ожидающие блоки finally.
Когда yield from <expr> используется, предоставленное выражение должно быть итерируемым. Значения, производимые при итерации по этому итерируемому объекту, передаются непосредственно вызывающей стороне текущих методов генератора. Любые значения, переданные с помощью send(), и любые исключения, переданные с помощью throw(), передаются подчинённому итератору, если у него есть соответствующие методы. Если это не так, то send() вызовет AttributeError или TypeError, в то время как throw() просто сразу же поднимет переданное исключение.
Когда подчинённый итератор завершается, атрибут value поднятого экземпляра StopIteration становится значением выражения yield. Он может быть явно установлен при подъёме StopIteration, или автоматически, когда подчинённый итератор является генератором (путём возврата значения из подгенератора).
Изменено в версии 3.3: Добавлен yield from <expr> для делегирования потока управления подчинённому итератору.
Скобки можно опустить, когда выражение yield является единственным выражением в правой части оператора присваивания.
См. также
- PEP 255 - Простые генераторы
-
Предложение по добавлению генераторов и оператора
yieldв Python. - PEP 342 - Корутины через расширенные генераторы
-
Предложение по расширению API и синтаксиса генераторов, делающее их пригодными для использования как простые корутины.
- PEP 380 - Синтаксис для делегирования подгенератору
-
Предложение по введению синтаксиса
yield_from, облегчающего делегирование подгенераторам. - PEP 525 - Асинхронные генераторы
-
Предложение, расширяющее PEP 492, добавив возможности генераторов к корутинным функциям.
6.2.9.1. Методы итератора генератора
В этом подразделе описываются методы итератора генератора. Их можно использовать для управления выполнением функции-генератора.
Обратите внимание, что вызов любого из методов генератора ниже, когда генератор уже выполняется, вызывает исключение ValueError.
-
generator.__next__() -
Начинает выполнение функции-генератора или возобновляет его в последней выполненной выражении yield. Когда функция-генератор возобновляется с помощью метода
__next__(), текущее выражение yield всегда вычисляется вNone. Затем выполнение продолжается до следующего выражения yield, где генератор приостанавливается снова, а значениеyield_listвозвращается вызывающему методу__next__(). Если генератор завершается, не сгенерировав другое значение, генерируется исключениеStopIteration.Этот метод обычно вызывается неявно, например, циклом
forили встроенной функциейnext().
-
generator.send(value) -
Возобновляет выполнение и «отправляет» значение в функцию-генератор. Аргумент value становится результатом текущего выражения yield. Метод
send()возвращает следующее значение, сгенерированное генератором, или вызываетStopIteration, если генератор завершается, не сгенерировав другое значение. Когдаsend()вызывается для запуска генератора, он должен быть вызван со значениемNoneв качестве аргумента, так как нет выражения yield, которое могло бы принять это значение.
-
generator.throw(value) - generator.throw(type[, value[, traceback]])
-
Возбуждает исключение в точке приостановки генератора и возвращает следующее сгенерированное значение функции-генератора. Если генератор завершается, не сгенерировав другое значение, возникает исключение
StopIteration. Если функция-генератор не перехватывает переданное исключение или генерирует другое исключение, то это исключение передаётся вызывающему коду.В типичном случае вызывается с экземпляром исключения, аналогично тому, как используется ключевое слово
raise.Для обратной совместимости поддерживается вторая сигнатура, следуя соглашению из старых версий Python. Аргумент type должен быть классом исключения, а value — экземпляром исключения. Если value не указан, конструктор type используется для получения экземпляра. Если traceback указан, он устанавливается для исключения; в противном случае любой существующий атрибут
__traceback__, хранящийся в value, может быть очищен.Изменено в версии 3.12: Вторая сигнатура (type[, value[, traceback]]) устарела и может быть удалена в будущих версиях Python.
-
generator.close() -
Возбуждает
GeneratorExitв точке приостановки функции-генератора. Если функция-генератор перехватывает исключение и возвращает значение, это значение возвращается методомclose(). Если генератор уже закрыт или возбуждаетGeneratorExit(не перехватывая исключение), методclose()возвращаетNone. Если генератор генерирует значение, возникаетRuntimeError. Если генератор возбуждает любое другое исключение, оно передается вызывающему коду. Если генератор уже завершился из-за исключения или нормального завершения,close()возвращаетNoneи не производит других действий.Изменено в версии 3.13: Если генератор возвращает значение при закрытии, это значение возвращается методом
close().
6.2.9.2. Примеры
Вот простой пример, демонстрирующий поведение генераторов и функций-генераторов:
>>> def echo(value=None):
... print("Execution starts when 'next()' is called for the first time.")
... try:
... while True:
... try:
... value = (yield value)
... except Exception as e:
... value = e
... finally:
... print("Don't forget to clean up when 'close()' is called.")
...
>>> generator = echo(1)
>>> print(next(generator))
Execution starts when 'next()' is called for the first time.
1
>>> print(next(generator))
None
>>> print(generator.send(2))
2
>>> generator.throw(TypeError, "spam")
TypeError('spam',)
>>> generator.close()
Don't forget to clean up when 'close()' is called.
Примеры, использующие yield from, см. в PEP 380: Синтаксис делегирования подгенератору в разделе «Что нового в Python».
6.2.9.3. Асинхронные генераторные функции
Наличие выражения yield в функции или методе, определённом с помощью async def, дополнительно определяет функцию как асинхронную генераторную функцию.
При вызове асинхронной генераторной функции она возвращает асинхронный итератор, известный как объект асинхронного генератора. Этот объект затем управляет выполнением генераторной функции. Объект асинхронного генератора обычно используется в операторе async for в функции сопрограммы аналогично тому, как объект генератора используется в операторе for.
Вызов одного из методов асинхронного генератора возвращает объект awaitable, и выполнение начинается, когда на этот объект выполняется операция ожидания. В этот момент выполнение переходит к первому выражению yield, где оно снова приостанавливается, возвращая значение yield_list ожидающей сопрограмме. Как и в случае с генератором, приостановление означает, что сохраняется всё локальное состояние, включая текущие привязки локальных переменных, указатель инструкции, внутренний стек вычислений и состояние обработки исключений. Когда выполнение возобновляется путём ожидания следующего объекта, возвращаемого методами асинхронного генератора, функция может продолжить точно так же, как если бы выражение yield было просто другим внешним вызовом. Значение выражения yield после возобновления зависит от метода, который возобновил выполнение. Если используется __anext__(), то результатом является None. В противном случае, если используется asend(), то результатом будет значение, переданное в этот метод.
Если асинхронный генератор завершается преждевременно из-за break, отмены задачи вызывающего кода или других исключений, код очистки асинхронного генератора будет выполнен и, возможно, вызовет исключения или обратится к переменным контекста в неожиданном контексте — возможно, после окончания срока действия задач, от которых он зависит, или во время завершения цикла событий, когда вызывается обработчик сборки мусора асинхронного генератора. Чтобы предотвратить это, вызывающий код должен явно закрыть асинхронный генератор, вызвав метод aclose(), чтобы завершить генератор и в конечном итоге отсоединить его от цикла событий.
В асинхронной генераторной функции выражения 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__() -
Возвращает awaitable, который при выполнении начинает выполнение асинхронного генератора или возобновляет его в последнем выполненном выражении yield. Когда асинхронная генераторная функция возобновляется с помощью метода
__anext__(), текущее выражение yield всегда оценивается какNoneв возвращаемом awaitable, который при выполнении будет продолжен до следующего выражения yield. Значениеyield_listвыражения yield является значением исключенияStopIteration, генерируемого завершающей сопрограммой. Если асинхронный генератор завершается без генерации другого значения, awaitable вместо этого генерирует исключениеStopAsyncIteration, сигнализирующее о завершении асинхронной итерации.Этот метод обычно вызывается неявно циклом
async for.
-
coroutine agen.asend(value) -
Возвращает awaitable, который при выполнении возобновляет выполнение асинхронного генератора. Как и метод
send()для генератора, это «отправляет» значение в асинхронную генераторную функцию, и аргумент value становится результатом текущего выражения yield. Возвращаемое awaitable методомasend()вернёт следующее значение, сгенерированное генератором, как значение сгенерированного исключенияStopIteration, или сгенерируетStopAsyncIteration, если асинхронный генератор завершается без генерации другого значения. При вызовеasend()для запуска асинхронного генератора, он должен вызываться сNoneв качестве аргумента, потому что нет выражения yield, которое могло бы принять значение.
-
coroutine agen.athrow(value) - coroutine agen.athrow(type[, value[, traceback]])
-
Возвращает awaitable, который генерирует исключение типа
typeв точке, где асинхронный генератор был приостановлен, и возвращает следующее значение, сгенерированное генераторной функцией, как значение сгенерированного исключенияStopIteration. Если асинхронный генератор завершается без генерации другого значения, генерируется исключениеStopAsyncIteration. Если генераторная функция не перехватывает переданное исключение или генерирует другое исключение, то при запуске awaitable это исключение передаётся вызывающему коду awaitable.Изменено в версии 3.12: Вторая сигнатура (type[, value[, traceback]]) устарела и может быть удалена в будущих версиях Python.
-
coroutine agen.aclose() -
Возвращает awaitable, который при выполнении сгенерирует
GeneratorExitв асинхронную генераторную функцию в точке, где она была приостановлена. Если асинхронная генераторная функция затем завершится успешно, уже закрыта или сгенерируетGeneratorExit(не перехватив исключение), то возвращаемое awaitable сгенерирует исключениеStopIteration. Любые дальнейшие awaitable, возвращаемые последующими вызовами асинхронного генератора, сгенерируют исключениеStopAsyncIteration. Если асинхронный генератор сгенерирует значение, будет сгенерировано исключениеRuntimeErrorawaitable. Если асинхронный генератор сгенерирует любое другое исключение, оно передаётся вызывающему коду awaitable. Если асинхронный генератор уже завершился из-за исключения или нормального завершения, последующие вызовыaclose()вернут awaitable, который ничего не делает.
6.3. Основные элементы
Основные элементы представляют собой самые тесно связанные операции языка. Их синтаксис:
primary ::= atom | attributeref | subscription | slicing | call
6.3.1. Обращения к атрибутам
Обращение к атрибуту — это основной элемент, за которым следует точка и имя:
attributeref ::= primary "." identifier
Основной элемент должен быть объектом типа, поддерживающего обращение к атрибутам, что большинство объектов делает. Затем от этого объекта запрашивается атрибут с указанным именем идентификатора. Тип и значение полученного атрибута определяются объектом. Несколько вычислений одного и того же обращения к атрибуту могут возвращать разные объекты.
Это поведение можно настроить, переопределив метод __getattribute__() или метод __getattr__(). Метод __getattribute__() вызывается первым и либо возвращает значение, либо вызывает исключение AttributeError, если атрибут недоступен.
Если возникает исключение AttributeError, и у объекта есть метод __getattr__(), этот метод вызывается как резервный вариант.
6.3.2. Подписки
Подписка экземпляра класса контейнерного класса обычно выбирает элемент из контейнера. Подписка обобщённого класса обычно возвращает объект GenericAlias.
subscription ::= primary "[" flexible_expression_list "]"
При подписке к объекту интерпретатор вычисляет основной элемент и список выражений.
Основной элемент должен быть объектом, поддерживающим подписки. Объект может поддерживать подписки, определив один или оба из методов __getitem__() и __class_getitem__(). При подписке к основному элементу вычисленное значение списка выражений будет передано одному из этих методов. Более подробную информацию о том, когда вызывается __class_getitem__ вместо __getitem__, см. в разделе __class_getitem__ по сравнению с __getitem__.
Если список выражений содержит по крайней мере одну запятую или если какие-либо из выражений помечены звёздочкой, список выражений будет вычисляться как кортеж tuple, содержащий элементы списка выражений. В противном случае список выражений будет вычисляться как значение единственного элемента списка.
Изменено в версии 3.11: Выражения в списке выражений могут быть помечены звёздочкой. См. PEP 646.
Для встроенных объектов существуют два типа объектов, которые поддерживают подписки через метод __getitem__():
- Отображения. Если основной элемент является отображением, список выражений должен вычисляться в объект, значение которого является одним из ключей отображения, и подписка выбирает значение в отображении, соответствующее этому ключу. Примером встроенного класса отображения является класс
dict. - Последовательности. Если основной элемент является последовательностью, список выражений должен вычисляться как целое число
intили как объект срезаslice(как обсуждается в следующем разделе). Примеры встроенных классов последовательностей включают классыstr,listиtuple.
Формальный синтаксис не делает специальных положений для отрицательных индексов в последовательностях. Однако все встроенные последовательности предоставляют метод __getitem__(), который интерпретирует отрицательные индексы, добавляя длину последовательности к индексу, так что, например, x[-1] выбирает последний элемент x. Результирующее значение должно быть целым неотрицательным числом, меньшим числа элементов в последовательности, а подписка выбирает элемент, индекс которого является этим значением (счёт от нуля). Поскольку поддержка отрицательных индексов и срезов происходит в методе объекта __getitem__(), подклассы, переопределяющие этот метод, должны явно добавить эту поддержку.
Объект string представляет собой особый вид последовательности, элементы которой — символы. Символ не является отдельным типом данных, а строкой ровно из одного символа.
6.3.3. Срезы
Срез выбирает диапазон элементов в объекте последовательности (например, строке, кортеже или списке). Срезы могут использоваться в качестве выражений или в качестве целей в операциях присваивания или del. Синтаксис среза:
slicing ::= primary "[" slice_list "]"
slice_list ::= slice_item ("," slice_item)* [","]
slice_item ::= expression | proper_slice
proper_slice ::= [lower_bound] ":" [upper_bound] [ ":" [stride] ]
lower_bound ::= expression
upper_bound ::= expression
stride ::= expression
Здесь существует неоднозначность в формальном синтаксисе: всё, что выглядит как список выражений, также выглядит как список срезов, поэтому любое обращение к подписке может интерпретироваться как срез. Вместо того, чтобы дополнительно усложнять синтаксис, это снимается неоднозначность путём определения того, что в этом случае интерпретация как подписка имеет приоритет над интерпретацией как среза (если список срезов не содержит правильного среза).
Семантика среза следующая. Основной элемент индексируется (используя тот же метод __getitem__(), что и при обычном обращении по подписке) с ключом, построенным из списка срезов следующим образом. Если список срезов содержит по крайней мере одну запятую, ключ — кортеж, содержащий преобразование элементов среза; в противном случае преобразование единственного элемента среза является ключом. Преобразование элемента среза, являющегося выражением, — это само выражение. Преобразование правильного среза — это объект среза (см. раздел Стандартная иерархия типов), чьи атрибуты start, stop и step являются значениями выражений, заданных как нижняя граница, верхняя граница и шаг соответственно, подставляя None для пропущенных выражений.
6.3.4. Вызовы
Вызов вызывает вызываемый объект (например, функцию) с возможно пустым набором аргументов:
call ::= primary "(" [argument_list [","] | comprehension] ")"
argument_list ::= positional_arguments ["," starred_and_keywords]
["," keywords_arguments]
| starred_and_keywords ["," keywords_arguments]
| keywords_arguments
positional_arguments ::= positional_item ("," positional_item)*
positional_item ::= assignment_expression | "*" expression
starred_and_keywords ::= ("*" expression | keyword_item)
("," "*" expression | "," keyword_item)*
keywords_arguments ::= (keyword_item | "**" expression)
("," keyword_item | "," "**" expression)*
keyword_item ::= identifier "=" expression
После позиционных и ключевых аргументов может быть необязательная заключительная запятая, которая не влияет на семантику.
Основной объект должен быть вызываемым объектом (пользовательские функции, встроенные функции, методы встроенных объектов, объекты классов, методы экземпляров классов и все объекты, имеющие метод __call__(), являются вызываемыми). Все выражения аргументов оцениваются перед попыткой вызова. Обратитесь к разделу Определения функций для синтаксиса формальных списков параметров.
Если присутствуют ключевые аргументы, они сначала преобразуются в позиционные аргументы следующим образом. Сначала создаётся список незаполненных слотов для формальных параметров. Если есть N позиционных аргументов, они помещаются в первые N слотов. Затем, для каждого ключевого аргумента, идентификатор используется для определения соответствующего слота (если идентификатор совпадает с именем первого формального параметра, используется первый слот и так далее). Если слот уже заполнен, генерируется исключение TypeError. В противном случае аргумент помещается в слот, заполняя его (даже если выражение None, оно заполняет слот). После обработки всех аргументов незаполненные слоты заполняются соответствующим значением по умолчанию из определения функции. (Значения по умолчанию вычисляются один раз при определении функции; таким образом, изменяемый объект, такой как список или словарь, используемый в качестве значения по умолчанию, будет совместно использоваться всеми вызовами, которые не указывают значение аргумента для соответствующего слота; это обычно следует избегать.) Если для некоторых незаполненных слотов не указано значение по умолчанию, генерируется исключение TypeError. В противном случае список заполненных слотов используется в качестве списка аргументов для вызова.
Деталь реализации CPython: Реализация может предоставлять встроенные функции, позиционные параметры которых не имеют имён, даже если они «именованные» для целей документации и, следовательно, не могут быть предоставлены в качестве ключевых. В CPython это относится к функциям, реализованным на C, которые используют PyArg_ParseTuple() для разбора их аргументов.
Если количество позиционных аргументов больше, чем количество формальных слотов параметров, генерируется исключение TypeError, если не присутствует формальный параметр с синтаксисом *identifier; в этом случае этот формальный параметр получает кортеж, содержащий избыточные позиционные аргументы (или пустой кортеж, если избыточных позиционных аргументов не было).
Если какой-либо ключевой аргумент не соответствует имени формального параметра, генерируется исключение TypeError, если не присутствует формальный параметр с синтаксисом **identifier; в этом случае этот формальный параметр получает словарь, содержащий избыточные ключевые аргументы (используя ключевые слова в качестве ключей и значения аргументов в качестве соответствующих значений), или новый пустой словарь, если избыточных ключевых аргументов не было.
Если в вызове функции появляется синтаксис *expression, expression должно быть итерируемым объектом. Элементы из этих итерируемых объектов обрабатываются как дополнительные позиционные аргументы. Для вызова f(x1, x2, *y, x3, x4), если y оценивается как последовательность y1, …, yM, это эквивалентно вызову с M+4 позиционными аргументами x1, x2, y1, …, yM, x3, x4.
Следствием этого является то, что, хотя синтаксис *expression может появляться после явных ключевых аргументов, он обрабатывается до ключевых аргументов (и любых аргументов **expression — см. ниже). Итак:
>>> def f(a, b): ... print(a, b) ... >>> f(b=1, *(2,)) 2 1 >>> f(a=1, *(2,)) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: f() got multiple values for keyword argument 'a' >>> f(1, *(2,)) 1 2
Необычно использовать как ключевые аргументы, так и синтаксис *expression в одном вызове, поэтому на практике эта путаница возникает нечасто.
Если в вызове функции появляется синтаксис **expression, expression должно быть отображением, содержимое которого обрабатывается как дополнительные ключевые аргументы. Если параметр, соответствующий ключу, уже получил значение (явным ключевым аргументом или из другого распаковки), генерируется исключение TypeError.
При использовании **expression, каждый ключ в этом отображении должен быть строкой. Каждое значение из отображения назначается первому формальному параметру, допускающему назначение ключевых слов, имя которого равно ключу. Ключ не обязательно должен быть идентификатором Python (например, "max-temp °F" допустимо, хотя он не будет соответствовать ни одному формальному параметру, который можно объявить). Если нет совпадения с формальным параметром, пара ключ-значение собирается параметром **, если он есть; если нет, генерируется исключение TypeError.
Формальные параметры с синтаксисом *identifier или **identifier не могут использоваться как слоты позиционных аргументов или как имена ключевых аргументов.
Изменено в версии 3.5: Функциональные вызовы принимают любое количество распаковок * и **, позиционные аргументы могут следовать за распаковками итерируемых объектов (*), а ключевые аргументы могут следовать за распаковками словарей (**). Первоначально предложено в PEP 448.
Вызов всегда возвращает некоторое значение, возможно None, если не возникает исключение. Способ вычисления этого значения зависит от типа вызываемого объекта.
Если это —
- пользовательская функция:
-
Блок кода функции выполняется, передавая ему список аргументов. Первым действием блока кода будет привязка формальных параметров к аргументам; это описано в разделе Определения функций. Когда блок кода выполняет оператор
return, это задаёт возвращаемое значение вызова функции. Если выполнение достигает конца блока кода без выполнения оператораreturn, возвращаемое значение являетсяNone. - встроенная функция или метод:
-
Результат зависит от интерпретатора; см. Встроенные функции для описаний встроенных функций и методов.
- объект класса:
-
Возвращается новый экземпляр этого класса.
- метод экземпляра класса:
-
Вызывается соответствующая пользовательская функция, со списком аргументов, на один элемент длиннее, чем список аргументов вызова: экземпляр становится первым аргументом.
- экземпляр класса:
-
Класс должен определить метод
__call__(); эффект затем такой же, как если бы этот метод был вызван.
6.4. Выражение await
Приостановить выполнение генератора на вызываемом объекте. Может использоваться только внутри генераторной функции.
await_expr ::= "await" primary
Добавлен в версии 3.5.
6.5. Оператор возведения в степень
Оператор возведения в степень связывается сильнее, чем унарные операторы слева; он связывается слабее, чем унарные операторы справа. Синтаксис:
power ::= (await_expr | primary) ["**" u_expr]
Таким образом, в нескорректированном ряду операторов возведения в степень и унарных операторов операторы вычисляются справа налево (это не ограничивает порядок вычисления операндов): -1**2 приводит к -1.
Оператор возведения в степень имеет такие же семантику, как встроенная функция pow(), когда она вызывается с двумя аргументами: она возвращает свой левый аргумент, возведённый в степень его правого аргумента. Числовые аргументы сначала преобразуются к общему типу, и результат имеет этот тип.
Для целочисленных операндов результат имеет тот же тип, что и операнды, если только второй аргумент не является отрицательным; в этом случае все аргументы преобразуются в float, и возвращается результат типа float. Например, 10**2 возвращает 100, но 10**-2 возвращает 0.01.
Возведение 0.0 в отрицательную степень приводит к ошибке ZeroDivisionError. Возведение отрицательного числа в дробную степень приводит к комплексному числу complex. (В более ранних версиях это вызывало ошибку ValueError.)
Эту операцию можно настроить, используя специальные методы __pow__() и __rpow__().
6.6. Унарные арифметические и побитовые операции
Все унарные арифметические и побитовые операции имеют одинаковый приоритет:
u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr
Унарный оператор - (минус) возвращает отрицание своего числового аргумента; операцию можно переопределить с помощью специального метода __neg__().
Унарный оператор + (плюс) возвращает свой числовой аргумент без изменений; операцию можно переопределить с помощью специального метода __pos__().
Унарный оператор ~ (инверсия) возвращает побитовую инверсию своего целочисленного аргумента. Побитовая инверсия x определяется как -(x+1). Он применяется только к целочисленным числам или к пользовательским объектам, которые переопределяют специальный метод __invert__().
Во всех трёх случаях, если аргумент не имеет соответствующего типа, возникает исключение TypeError.
6.7. Бинарные арифметические операции
Бинарные арифметические операции имеют стандартные уровни приоритета. Обратите внимание, что некоторые из этих операций также применяются к определённым нечисловым типам. Помимо оператора возведения в степень, существуют только два уровня: один для умножительных операторов и один для операторов сложения:
m_expr ::= u_expr | m_expr "*" u_expr | m_expr "@" m_expr |
m_expr "//" u_expr | m_expr "/" u_expr |
m_expr "%" u_expr
a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr
Оператор * (умножение) возвращает произведение своих аргументов. Аргументы должны быть либо оба числа, либо один аргумент должен быть целым числом, а другой — последовательностью. В первом случае числа преобразуются к общему типу и затем перемножаются. Во втором случае выполняется повторение последовательности; отрицательный коэффициент повторения возвращает пустую последовательность.
Эту операцию можно настроить, используя специальные методы __mul__() и __rmul__().
Оператор @ (со знаком @) предназначен для матричного умножения. Встроенные типы Python не реализуют этот оператор.
Эту операцию можно настроить, используя специальные методы __matmul__() и __rmatmul__().
Добавлен в версии 3.5.
Операторы / (деление) и // (целочисленное деление) возвращают частное от деления своих аргументов. Числовые аргументы сначала преобразуются к общему типу. Деление целых чисел возвращает число с плавающей точкой, в то время как целочисленное деление целых чисел возвращает целое число; результат соответствует математическому делению с применением функции «floor» к результату. Деление на ноль вызывает исключение ZeroDivisionError.
Операцию деления можно настроить, используя специальные методы __truediv__() и __rtruediv__(). Операцию целочисленного деления можно настроить, используя специальные методы __floordiv__() и __rfloordiv__().
Оператор % (остаток от деления) возвращает остаток от деления первого аргумента на второй. Числовые аргументы сначала преобразуются к общему типу. Ноль в качестве правого аргумента вызывает исключение ZeroDivisionError. Аргументы могут быть числами с плавающей точкой, например, 3.14%0.7 равно 0.34 (так как 3.14 равно 4*0.7 + 0.34.) Оператор остатка от деления всегда возвращает результат со знаком, совпадающим со знаком второго операнда (или ноль); абсолютное значение результата строго меньше абсолютного значения второго операнда [1].
Операции целочисленного деления и остатка от деления связаны следующим тождеством: x == (x//y)*y + (x%y). Целочисленное деление и остаток также связаны с встроенной функцией divmod(): divmod(x, y) == (x//y,
x%y). [2].
Помимо выполнения операции остатка от деления над числами, оператор % также перегружен объектами строк для выполнения форматирования строк старого стиля (также известного как интерполяция). Синтаксис форматирования строк описан в Справочнике по библиотеке Python, раздел Форматирование строк в стиле printf.
Операцию остатка от деления можно настроить, используя специальные методы __mod__() и __rmod__().
Операции целочисленного деления, остатка от деления и функции divmod() не определены для комплексных чисел. Вместо этого, преобразуйте в число с плавающей точкой, используя функцию abs(), если это уместно.
Оператор + (сложение) возвращает сумму своих аргументов. Аргументы должны быть либо оба числа, либо обе последовательности одного типа. В первом случае числа преобразуются к общему типу и затем складываются. Во втором случае последовательности конкатенируются.
Эту операцию можно настроить, используя специальные методы __add__() и __radd__().
Оператор - (вычитание) возвращает разность своих аргументов. Числовые аргументы сначала преобразуются к общему типу.
Эту операцию можно настроить, используя специальные методы __sub__() и __rsub__().
6.8. Операции сдвига
Операции сдвига имеют более низкий приоритет, чем арифметические операции:
shift_expr ::= a_expr | shift_expr ("<<" | ">>") a_expr
Эти операторы принимают целые числа в качестве аргументов. Они сдвигают первый аргумент влево или вправо на количество бит, указанное вторым аргументом.
Операцию сдвига влево можно настроить, используя специальные методы __lshift__() и __rlshift__(). Операцию сдвига вправо можно настроить, используя специальные методы __rshift__() и __rrshift__().
Сдвиг вправо на n бит определяется как целочисленное деление на pow(2,n). Сдвиг влево на n бит определяется как умножение на pow(2,n).
6.9. Бинарные побитовые операции
Каждая из трёх побитовых операций имеет разный приоритет:
and_expr ::= shift_expr | and_expr "&" shift_expr xor_expr ::= and_expr | xor_expr "^" and_expr or_expr ::= xor_expr | or_expr "|" xor_expr
Оператор & возвращает побитовое И своих аргументов, которые должны быть целыми числами, или один из них должен быть пользовательским объектом, переопределяющим специальные методы __and__() или __rand__().
Оператор ^ возвращает побитовое исключающее ИЛИ (XOR) своих аргументов, которые должны быть целыми числами, или один из них должен быть пользовательским объектом, переопределяющим специальные методы __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) сравниваются лексикографически, используя числовые значения кодов Юникода (результат встроенной функцииord()) их символов. [3]Строки и бинарные последовательности не могут быть напрямую сравнены.
-
Последовательности (экземпляры
tuple,listилиrange) могут быть сравнены только внутри каждого из их типов, с ограничением, что диапазоны не поддерживают сравнение по порядку. Сравнение на равенство между этими типами приводит к неравенству, а сравнение по порядку между этими типами вызываетTypeError.Последовательности сравниваются лексикографически, используя сравнение соответствующих элементов. Встроенные контейнеры обычно предполагают, что идентичные объекты равны самим себе. Это позволяет им обходить проверки равенства для идентичных объектов, чтобы повысить производительность и сохранить внутренние инварианты.
Лексикографическое сравнение между встроенными коллекциями работает следующим образом:
- Для сравнения двух коллекций на равенство они должны быть одного типа, иметь одинаковую длину и каждая пара соответствующих элементов должна сравниваться на равенство (например,
[1,2] == (1,2)ложно, потому что типы не одинаковы). - Коллекции, которые поддерживают сравнение по порядку, упорядочиваются так же, как и их первые неравные элементы (например,
[1,2,x] <= [1,2,y]имеет то же значение, что иx <= y). Если соответствующего элемента нет, то более короткая коллекция упорядочивается первой (например,[1,2] < [1,2,3]истинно).
- Для сравнения двух коллекций на равенство они должны быть одного типа, иметь одинаковую длину и каждая пара соответствующих элементов должна сравниваться на равенство (например,
-
Словари (экземпляры
dict) сравниваются на равенство только в том случае, если они имеют равные(key, value)пары. Сравнение на равенство ключей и значений обеспечивает рефлексивность.Сравнения по порядку (
<,>,<=, и>=) вызываютTypeError. -
Множества (экземпляры
setилиfrozenset) могут сравниваться внутри и между своими типами.Они определяют операторы сравнения по порядку, обозначающие тесты подмножества и надмножества. Эти отношения не определяют полных порядков (например, два множества
{1,2}и{2,3}не равны, не являются подмножествами друг друга, и не являются надмножествами друг друга). Следовательно, множества не являются подходящими аргументами для функций, которые зависят от полного порядка (например,min(),max()иsorted()производят неопределённые результаты, если в качестве входных данных подан список множеств).Сравнение множеств обеспечивает рефлексивность её элементов.
- Большинство других встроенных типов не реализуют методы сравнения, поэтому они наследуют стандартное поведение сравнения.
Пользовательские классы, которые настраивают своё поведение сравнения, должны, по возможности, следовать некоторым правилам согласованности:
-
Сравнение на равенство должно быть рефлексивным. Другими словами, идентичные объекты должны сравниваться на равенство:
x is yподразумеваетx == y -
Сравнение должно быть симметричным. Другими словами, следующие выражения должны иметь одинаковый результат:
x == yиy == xx != yиy != xx < yиy > xx <= yиy >= x -
Сравнение должно быть транзитивным. Следующие (неполные) примеры иллюстрируют это:
x > y and y > zподразумеваетx > zx < y and y <= zподразумеваетx < z -
Обратное сравнение должно давать логическое отрицание. Другими словами, следующие выражения должны иметь одинаковый результат:
x == yиnot x != yx < yиnot x >= y(для полного порядка)x > yиnot x <= y(для полного порядка)Последние два выражения относятся к полностью упорядоченным коллекциям (например, к последовательностям, но не к множествам или словарям). См. также декоратор
total_ordering(). - Результат
hash()должен соответствовать равенству. Объекты, которые равны, должны иметь одинаковое значение хэша или быть помечены как нехешируемые.
Python не навязывает этих правил согласованности. Фактически, значения «не число» — пример того, как этим правилам не следуют.
6.10.2. Операции проверки принадлежности
Операторы in и not in проверяют принадлежность. x in
s вычисляет значение True, если x является элементом s, и False в противном случае. x not in s возвращает отрицание x in s. Все встроенные последовательности и типы множеств, а также словари поддерживают эту проверку, причём для словарей in проверяет наличие заданного ключа. Для типов контейнеров, таких как списки, кортежи, множества, неизменяемые множества, словари или очереди 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)
Выражения присваивания должны быть заключены в скобки, когда они используются в качестве операторов выражений и как подвыражения в операциях срезов, условных операциях, лямбда-выражениях, аргументах ключевых слов, выражениях с генераторами и в assert, with, и assignment операторах. Во всех остальных случаях, где они могут быть использованы, скобки не требуются, включая операторы if и while.
Добавлен в версии 3.8: См. PEP 572 для получения дополнительной информации об выражениях присваивания.
6.13. Условные выражения
conditional_expression ::= or_test ["if" or_test "else" expression] expression ::= conditional_expression | lambda_expr
Условные выражения (иногда называемые «тернарным оператором») имеют самый низкий приоритет среди всех операций Python.
Выражение x if C else y сначала вычисляет условие C, а не x. Если C истинно, вычисляется x и возвращается его значение; в противном случае вычисляется y и возвращается его значение.
См. PEP 308 для получения дополнительной информации об условных выражениях.
6.14. Лямбда-выражения
lambda_expr ::= "lambda" [parameter_list] ":" expression
Лямбда-выражения (иногда называемые лямбда-формами) используются для создания анонимных функций. Выражение lambda parameters: expression возвращает объект функции. Этот безымянный объект ведёт себя как объект функции, определённый как:
def <lambda>(parameters):
return expression
См. раздел Определения функций для синтаксиса списков параметров. Обратите внимание, что функции, созданные с помощью лямбда-выражений, не могут содержать операторы или аннотации.
6.15. Списки выражений
starred_expression ::= ["*"] or_expr
flexible_expression ::= assignment_expression | starred_expression
flexible_expression_list ::= flexible_expression ("," flexible_expression)* [","]
starred_expression_list ::= starred_expression ("," starred_expression)* [","]
expression_list ::= expression ("," expression)* [","]
yield_list ::= expression_list | starred_expression "," [starred_expression_list]
За исключением случаев, когда список выражений является частью отображения списка или множества, список выражений, содержащий по меньшей мере одну запятую, возвращает кортеж. Длина кортежа равна числу выражений в списке. Выражения вычисляются слева направо.
Звёздочка * обозначает распаковку итерируемых объектов. Её операнд должен быть итерируемым объектом. Итерируемый объект расширяется в последовательность элементов, которые включаются в новый кортеж, список или множество на месте распаковки.
Добавлен в версии 3.5: Распаковка итерируемых объектов в списки выражений, первоначально предложенная в PEP 448.
Добавлен в версии 3.11: Любой элемент в списке выражений может быть звездочным. См. PEP 646.
Конечная запятая требуется только для создания кортежа из одного элемента, например, 1,; она необязательна во всех остальных случаях. Одно выражение без конечной запятой не создаёт кортеж, а возвращает значение этого выражения. (Чтобы создать пустой кортеж, используйте пустую пару скобок: ().)
6.16. Порядок вычисления
Python вычисляет выражения слева направо. Обратите внимание, что при вычислении присваивания правая часть вычисляется перед левой.
В следующих строках выражения будут вычисляться в арифметическом порядке их индексов:
expr1, expr2, expr3, expr4
(expr1, expr2, expr3, expr4)
{expr1: expr2, expr3: expr4}
expr1 + expr2 * (expr3 - expr4)
expr1(expr2, expr3, *expr4, **expr5)
expr3, expr4 = expr1, expr2
6.17. Приоритет операторов
В следующей таблице перечислены приоритеты операторов в Python, от наивысшего (самое сильное связывание) до наименьшего (наименьшее связывание). Операторы в одной строке имеют одинаковый приоритет. Если синтаксис не указан явно, операторы являются бинарными. Операторы в одной строке группируются слева направо (за исключением возведения в степень и условных выражений, которые группируются справа налево).
Обратите внимание, что сравнения, проверки на вхождение и проверки тождественности имеют одинаковый приоритет и обладают свойством цепочки слева направо, как описано в разделе Сравнения.
Оператор | Описание |
|---|---|
|
| Связывание или выражение в скобках, представление списка, представление словаря, представление множества |
| Индексация, срезы, вызов, обращение к атрибуту |
Выражение await | |
| Возведение в степень [5] |
| Положительный, отрицательный, побитовое НЕ |
| Умножение, матричное умножение, деление, целочисленное деление, остаток от деления [6] |
| Сложение и вычитание |
| Сдвиги |
| Побитовое И |
| Побитовое ИСКЛЮЧАЮЩЕЕ ИЛИ |
| Побитовое ИЛИ |
Сравнения, включая проверки на вхождение и проверки тождественности | |
Логическое НЕ | |
Логическое И | |
Логическое ИЛИ | |
| Условное выражение |
Выражение лямбда | |
| Выражение присваивания |
Примечания
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/reference/expressions.html