Выражения
В этой главе объясняется значение элементов выражений в 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" or_test [comp_iter]
Генератор состоит из одного выражения, за которым следует как минимум одна часть for и ноль или более частей for или if. В этом случае элементами нового контейнера становятся результаты вычисления выражения при рассмотрении каждой части for или if как блока, вложенного слева направо, и вычислении выражения для получения элемента при каждом достижении самого внутреннего блока.
Однако, за исключением итерируемого выражения в самой левой части for, генератор выполняется в отдельной неявно вложенной области видимости. Это гарантирует, что имена, присвоенные в целевом списке, не «просочатся» во внешнюю область видимости.
Итерируемое выражение в самой левой части for вычисляется непосредственно во внешней области видимости, а затем передаётся как аргумент неявно вложенной области видимости. Последующие части for и любое условие фильтрации в самой левой части for нельзя вычислить во внешней области видимости, поскольку они могут зависеть от значений, полученных из самого левого итерируемого объекта. Например: [x*y for x in range(10) for y in range(x, x+10)].
Чтобы гарантировать, что генератор всегда создаёт контейнер соответствующего типа, выражения yield и yield from запрещены в неявно вложенной области видимости.
Начиная с Python 3.6, в функции async def для перебора асинхронного итератора можно использовать часть async for. Генератор в функции async def может содержать после начального выражения часть for или async for, дополнительные части for или async for, а также выражения await. Если генератор содержит части async for, выражения await или другие асинхронные генераторы, он называется асинхронным генератором. Асинхронный генератор может приостанавливать выполнение функции-корутины, в которой он находится. См. также PEP 530.
Добавлено в версии 3.6: Добавлены асинхронные генераторы.
Изменено в версии 3.8: yield и yield from запрещены в неявно вложенной области видимости.
Изменено в версии 3.11: Теперь асинхронные генераторы разрешены внутри генераторов в асинхронных функциях. Внешние генераторы неявно становятся асинхронными.
6.2.5. Записи списков
Запись списка — это, возможно, пустая последовательность выражений, заключённая в квадратные скобки:
list_display ::= "[" [starred_list | comprehension] "]"
В результате записи списка создаётся новый объект-список, содержимое которого задаётся либо списком выражений, либо генератором. Если указан список выражений, разделённых запятыми, его элементы вычисляются слева направо и в том же порядке помещаются в объект-список. Если указан генератор, список создаётся из элементов, полученных в результате его выполнения.
6.2.6. Записи множеств
Запись множества обозначается фигурными скобками и отличается от записи словаря отсутствием двоеточий, разделяющих ключи и значения:
set_display ::= "{" (starred_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" expression_list | yield_from
Выражение yield используется при определении функции генератора или функции асинхронного генератора и поэтому может использоваться только в теле определения функции. Использование выражения yield в теле функции превращает её в функцию-генератор, а его использование в теле функции async def превращает эту корутинную функцию в функцию асинхронного генератора. Например:
def gen(): # defines a generator function
yield 123
async def agen(): # defines an asynchronous generator function
yield 123
Из-за побочных эффектов в содержащей области видимости выражения yield запрещены в неявно определённых областях видимости, используемых для реализации включений и генераторных выражений.
Изменено в версии 3.8: Выражения yield запрещены в неявно вложенных областях видимости, используемых для реализации включений и генераторных выражений.
Функции-генераторы описаны ниже, а функции асинхронных генераторов описаны отдельно в разделе Функции асинхронных генераторов.
При вызове функции-генератора она возвращает итератор, известный как генератор. Этот генератор управляет выполнением функции-генератора. Выполнение начинается при вызове одного из методов генератора. В этот момент оно продолжается до первого выражения yield, на котором снова приостанавливается, возвращая вызывающему коду генератора значение expression_list или None, если expression_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, где генератор снова приостанавливается, а значениеexpression_listвозвращается вызывающему коду__next__(). Если генератор завершится, не выдав другого значения, будет вызвано исключениеStopIteration.Обычно этот метод вызывается неявно, например циклом
forили встроенной функциейnext().
-
generator.send(value) -
Возобновляет выполнение и «отправляет» значение в функцию-генератор. Аргумент value становится результатом текущего выражения yield. Метод
send()возвращает следующее значение, выданное генератором, или вызывает исключениеStopIteration, если генератор завершится, не выдав другого значения. При вызовеsend()для запуска генератора в качестве аргумента необходимо передатьNone, поскольку нет выражения yield, которое могло бы получить это значение.
-
generator.throw(value) - generator.throw(type[, value[, traceback]])
-
Вызывает исключение в точке, где генератор был приостановлен, и возвращает следующее значение, выданное функцией-генератором. Если генератор завершится, не выдав другого значения, будет вызвано исключение
StopIteration. Если функция-генератор не перехватит переданное исключение или вызовет другое исключение, оно будет передано вызывающему коду.Обычно этот метод вызывается с единственным экземпляром исключения, подобно использованию ключевого слова
raise.Однако для обратной совместимости поддерживается и вторая сигнатура, соответствующая соглашению из старых версий Python. Аргумент type должен быть классом исключения, а value — экземпляром исключения. Если value не указан, для получения экземпляра вызывается конструктор type. Если указан traceback, он присваивается исключению; в противном случае существующий атрибут
__traceback__, сохранённый в value, может быть очищен.
-
generator.close() -
Вызывает исключение
GeneratorExitв точке, где функция-генератор была приостановлена. Если после этого функция-генератор корректно завершается, уже закрыта или вызываетGeneratorExit(не перехватывая это исключение), метод close возвращает управление вызывающему коду. Если генератор выдаёт значение, вызывается исключениеRuntimeError. Если генератор вызывает любое другое исключение, оно передаётся вызывающему коду.close()ничего не делает, если генератор уже завершился из-за исключения или штатного выхода.
6.2.9.2. Примеры
Ниже приведён простой пример, демонстрирующий поведение генераторов и функций-генераторов:
>>> def echo(value=None):
... print("Execution starts when 'next()' is called for the first time.")
... try:
... while True:
... try:
... value = (yield value)
... except Exception as e:
... value = e
... finally:
... print("Don't forget to clean up when 'close()' is called.")
...
>>> generator = echo(1)
>>> print(next(generator))
Execution starts when 'next()' is called for the first time.
1
>>> print(next(generator))
None
>>> print(generator.send(2))
2
>>> generator.throw(TypeError, "spam")
TypeError('spam',)
>>> generator.close()
Don't forget to clean up when 'close()' is called.
Примеры использования yield from см. в разделе PEP 380: синтаксис делегирования подгенератору документа «Что нового в Python».
6.2.9.3. Функции асинхронных генераторов
Наличие выражения yield в функции или методе, определённом с помощью async def, дополнительно определяет эту функцию как функцию асинхронного генератора.
При вызове функции асинхронного генератора она возвращает асинхронный итератор, известный как объект асинхронного генератора. Этот объект управляет выполнением функции-генератора. Объект асинхронного генератора обычно используется в операторе async for внутри корутинной функции, подобно тому как объект генератора используется в операторе for.
Вызов одного из методов асинхронного генератора возвращает объект ожидаемого объекта, выполнение которого начинается при его ожидании. В этот момент выполнение продолжается до первого выражения yield, где снова приостанавливается, возвращая ожидающей корутине значение expression_list. Как и в случае генератора, приостановка означает сохранение всего локального состояния, включая текущие привязки локальных переменных, указатель инструкции, внутренний стек вычислений и состояние обработки исключений. Когда выполнение возобновляется ожиданием следующего объекта, возвращённого методами асинхронного генератора, функция может продолжить работу точно так же, как если бы выражение yield было обычным внешним вызовом. Значение выражения yield после возобновления зависит от метода, который возобновил выполнение. Если используется __anext__(), результатом будет None. В противном случае, если используется asend(), результатом будет значение, переданное этому методу.
Если асинхронный генератор неожиданно завершится раньше времени из-за break, отмены вызывающей задачи или других исключений, будет выполнен код очистки генератора, который может вызвать исключения или получить доступ к контекстным переменным в неожиданном контексте — возможно, уже после завершения задач, от которых он зависит, или во время завершения цикла событий, когда вызывается обработчик сборки мусора асинхронных генераторов. Чтобы этого избежать, вызывающий код должен явно закрыть асинхронный генератор, вызвав метод aclose(), чтобы завершить генератор и в конечном счёте отсоединить его от цикла событий.
В функции асинхронного генератора выражения yield разрешены в любом месте конструкции try. Однако если асинхронный генератор не будет возобновлён до завершения (при достижении нулевого счётчика ссылок или сборке мусора), выражение yield внутри конструкции try может помешать выполнению ожидающих блоков finally. В этом случае цикл событий или планировщик, выполняющий асинхронный генератор, должен вызвать метод aclose() итератора асинхронного генератора и выполнить полученный объект корутины, что позволит выполнить все ожидающие блоки finally.
Чтобы обеспечить финализацию при завершении цикла событий, цикл событий должен определить функцию финализатора, принимающую итератор асинхронного генератора и, предположительно, вызывающую aclose() и выполняющую корутину. Этот финализатор можно зарегистрировать вызовом sys.set_asyncgen_hooks(). При первой итерации итератор асинхронного генератора сохраняет зарегистрированный финализатор, который будет вызван при финализации. Пример реализации метода финализатора см. в реализации asyncio.Loop.shutdown_asyncgens в файле Lib/asyncio/base_events.py.
Выражение yield from <expr> является синтаксической ошибкой при использовании в функции асинхронного генератора.
6.2.9.4. Методы итератора асинхронного генератора
В этом подразделе описаны методы итератора асинхронного генератора, используемые для управления выполнением функции-генератора.
-
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(value) - корутина 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
Первичное выражение должно вычисляться в объект типа, поддерживающего ссылки на атрибуты; таких объектов большинство. Затем у этого объекта запрашивается атрибут с именем, указанным идентификатором. Тип и значение результата определяются объектом. При повторных вычислениях одной и той же ссылки на атрибут могут получаться разные объекты.
Это поведение можно настроить, переопределив метод __getattribute__() или метод __getattr__(). Сначала вызывается метод __getattribute__(); он либо возвращает значение, либо вызывает исключение AttributeError, если атрибут недоступен.
Если вызывается исключение AttributeError и у объекта есть метод __getattr__(), этот метод вызывается в качестве запасного варианта.
6.3.2. Индексация
Индексация экземпляра класса-контейнера обычно выбирает элемент из контейнера. Индексация обобщённого класса обычно возвращает объект GenericAlias.
subscription ::= primary "[" expression_list "]"
При индексации объекта интерпретатор вычисляет первичное выражение и список выражений.
Первичное выражение должно вычисляться в объект, поддерживающий индексацию. Объект может поддерживать индексацию, определяя один или оба метода: __getitem__() и __class_getitem__(). При индексации первичного выражения вычисленный результат списка выражений передаётся одному из этих методов. Подробнее о том, когда вызывается __class_getitem__ вместо __getitem__, см. в разделе __class_getitem__ и __getitem__.
Если список выражений содержит хотя бы одну запятую, он вычисляется в tuple, содержащий элементы списка выражений. В противном случае список выражений вычисляется в значение единственного элемента списка.
Для встроенных объектов существуют два типа объектов, поддерживающих индексацию с помощью __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, она задаёт возвращаемое значение вызова функции. - встроенная функция или метод:
-
Результат определяется интерпретатором; описание встроенных функций и методов см. в разделе Встроенные функции.
- объект-класс:
-
Возвращается новый экземпляр этого класса.
- метод экземпляра класса:
-
Вызывается соответствующая пользовательская функция со списком аргументов, который на один элемент длиннее списка аргументов вызова: экземпляр становится первым аргументом.
- экземпляр класса:
-
Класс должен определять метод
__call__(); тогда результат будет таким же, как если бы был вызван этот метод.
6.4. Выражение await
Приостановить выполнение сопрограммы, ожидая объект ожидания. Может использоваться только внутри функции-сопрограммы.
await_expr ::= "await" primary
Добавлено в версии 3.5.
6.5. Оператор возведения в степень
Оператор возведения в степень имеет более высокий приоритет, чем унарные операторы слева от него, и более низкий, чем унарные операторы справа от него. Синтаксис:
power ::= (await_expr | primary) ["**" u_expr]
Таким образом, в неперегруппированной последовательности операторов возведения в степень и унарных операторов они вычисляются справа налево (это не ограничивает порядок вычисления операндов): результат -1**2 — -1.
Семантика оператора возведения в степень совпадает с семантикой встроенной функции pow() при вызове с двумя аргументами: левый аргумент возводится в степень, заданную правым аргументом. Сначала числовые аргументы преобразуются к общему типу, и результат имеет этот тип.
Для операндов типа int результат имеет тот же тип, что и операнды, если только второй аргумент не отрицательный; в этом случае все аргументы преобразуются в float, и возвращается результат типа float. Например, 10**2 возвращает 100, а 10**-2 возвращает 0.01.
Возведение 0.0 в отрицательную степень вызывает исключение ZeroDivisionError. Возведение отрицательного числа в дробную степень даёт число типа complex. (В более ранних версиях вызывалось исключение ValueError.)
Это действие можно настроить с помощью специального метода __pow__().
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__().
Оператор @ (at) предназначен для умножения матриц. Ни один встроенный тип Python не реализует этот оператор.
Добавлено в версии 3.5.
Операторы / (деление) и // (деление нацело) возвращают частное своих аргументов. Сначала числовые аргументы преобразуются к общему типу. Деление целых чисел даёт число с плавающей точкой, а деление целых чисел нацело — целое число; результат представляет собой результат математического деления с применением функции «floor». Деление на ноль вызывает исключение ZeroDivisionError.
Это действие можно настроить с помощью специальных методов __truediv__() и __floordiv__().
Оператор % (остаток от деления) возвращает остаток от деления первого аргумента на второй. Сначала числовые аргументы преобразуются к общему типу. Нулевой правый аргумент вызывает исключение ZeroDivisionError. Аргументы могут быть числами с плавающей точкой, например 3.14%0.7 равно 0.34 (поскольку 3.14 равно 4*0.7 + 0.34). Оператор остатка всегда возвращает результат с тем же знаком, что и второй операнд (или ноль); абсолютное значение результата строго меньше абсолютного значения второго операнда [1].
Операторы деления нацело и остатка связаны следующим тождеством: x == (x//y)*y + (x%y). Деление нацело и остаток также связаны со встроенной функцией divmod(): divmod(x, y) == (x//y,
x%y). [2].
Помимо выполнения операции остатка над числами, оператор % перегружен для строковых объектов и выполняет форматирование строк в старом стиле (также известное как интерполяция). Синтаксис форматирования строк описан в справочнике по стандартной библиотеке Python, раздел Форматирование строк в стиле printf.
Операцию нахождения остатка можно настроить с помощью специального метода __mod__().
Оператор деления нацело, оператор остатка и функция divmod() не определены для комплексных чисел. Вместо этого при необходимости преобразуйте число в число с плавающей точкой с помощью функции abs().
Оператор + (сложение) возвращает сумму своих аргументов. Аргументы должны быть либо оба числами, либо последовательностями одного типа. В первом случае числа преобразуются к общему типу, а затем складываются. Во втором случае последовательности объединяются.
Это действие можно настроить с помощью специальных методов __add__() и __radd__().
Оператор - (вычитание) возвращает разность своих аргументов. Сначала числовые аргументы преобразуются к общему типу.
Это действие можно настроить с помощью специального метода __sub__().
6.8. Операции сдвига
Операции сдвига имеют более низкий приоритет, чем арифметические операции:
shift_expr ::= a_expr | shift_expr ("<<" | ">>") a_expr
Эти операторы принимают целые числа в качестве аргументов. Они сдвигают первый аргумент влево или вправо на указанное вторым аргументом количество битов.
Это действие можно настроить с помощью специальных методов __lshift__() и __rshift__().
Сдвиг вправо на n бит определяется как деление нацело на pow(2,n). Сдвиг влево на n бит определяется как умножение на pow(2,n).
6.9. Бинарные побитовые операции
Каждая из трёх побитовых операций имеет свой уровень приоритета:
and_expr ::= shift_expr | and_expr "&" shift_expr xor_expr ::= and_expr | xor_expr "^" and_expr or_expr ::= xor_expr | or_expr "|" xor_expr
Оператор & возвращает побитовое И своих аргументов, которыми должны быть целые числа; также один из аргументов может быть пользовательским объектом, переопределяющим специальные методы __and__() или __rand__().
Оператор ^ возвращает побитовое исключающее ИЛИ своих аргументов, которыми должны быть целые числа; также один из аргументов может быть пользовательским объектом, переопределяющим специальные методы __xor__() или __rxor__().
Оператор | возвращает побитовое (включающее) ИЛИ своих аргументов, которыми должны быть целые числа; также один из аргументов может быть пользовательским объектом, переопределяющим специальные методы __or__() или __ror__().
6.10. Сравнения
В отличие от C, в Python все операции сравнения имеют одинаковый приоритет, который ниже приоритета любых арифметических операций, операций сдвига или побитовых операций. Также в отличие от C, выражения вида a < b < c интерпретируются так, как принято в математике:
comparison ::= or_expr (comp_operator or_expr)*
comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="
| "is" ["not"] | ["not"] "in"
Результатом сравнений являются логические значения: True или False. Пользовательские методы расширенного сравнения могут возвращать не логические значения. В этом случае Python вызовет bool() для такого значения в логическом контексте.
Сравнения можно произвольно объединять в цепочки, например, x < y <= z эквивалентно x < y and y <= z, за исключением того, что y вычисляется только один раз (но в обоих случаях z вообще не вычисляется, если x < y оказывается ложным).
Формально, если a, b, c, …, y, z — выражения, а op1, op2, …, opN — операторы сравнения, то a op1 b op2 c ... y opN z эквивалентно a op1 b and b op2 c and ... y opN z, за исключением того, что каждое выражение вычисляется не более одного раза.
Обратите внимание, что a op1 b op2 c не подразумевает никакого сравнения между a и c, поэтому, например, x < y > z вполне допустимо (хотя, возможно, выглядит не очень красиво).
6.10.1. Сравнение значений
Операторы <, >, ==, >=, <= и != сравнивают значения двух объектов. Объекты не обязаны иметь одинаковый тип.
В главе Объекты, значения и типы говорится, что у объектов есть значение (помимо типа и идентичности). Значение объекта в Python — довольно абстрактное понятие: например, не существует стандартного способа доступа к значению объекта. Кроме того, нет требования, чтобы значение объекта формировалось каким-либо определённым способом, например состояло из всех его атрибутов данных. Операторы сравнения реализуют конкретное представление о том, что является значением объекта. Их можно рассматривать как средства косвенного определения значения объекта посредством реализации сравнения.
Поскольку все типы являются прямыми или косвенными подтипами object, они наследуют поведение сравнения по умолчанию от object. Типы могут настраивать поведение сравнения, реализуя методы расширенного сравнения, такие как __lt__(), описанные в разделе Базовая настройка.
Поведение сравнения на равенство по умолчанию (== и !=) основано на идентичности объектов. Поэтому сравнение экземпляров с одинаковой идентичностью даёт равенство, а сравнение экземпляров с разной идентичностью — неравенство. Одной из причин такого поведения по умолчанию является стремление к тому, чтобы все объекты были рефлексивны (то есть из x is y следует x == y).
Сравнение на порядок по умолчанию (<, >, <= и >=) не определено; попытка его выполнить вызывает исключение TypeError. Причина такого поведения по умолчанию — отсутствие аналога инварианта, существующего для равенства.
Поведение сравнения на равенство по умолчанию, согласно которому экземпляры с разной идентичностью всегда не равны, может не соответствовать требованиям типов, для которых имеет смысл определение значения объекта и сравнение по значениям. Такие типы должны настраивать поведение сравнения; и действительно, ряд встроенных типов это делает.
В следующем списке описано поведение сравнения для наиболее важных встроенных типов.
-
Числа встроенных числовых типов (Числовые типы — int, float, complex) и стандартных библиотечных типов
fractions.Fractionиdecimal.Decimalможно сравнивать как внутри одного типа, так и между типами, с ограничением, что комплексные числа не поддерживают сравнение на порядок. В пределах возможностей используемых типов сравнение соответствует математическому (алгоритмически корректному) результату без потери точности.Особым случаем являются значения «не число»
float('NaN')иdecimal.Decimal('NaN'). Любое упорядоченное сравнение числа со значением «не число» ложно. Из этого следует неожиданное свойство: значения «не число» не равны сами себе. Например, еслиx = float('NaN'),3 < x,x < 3иx == xвсегда ложны, аx != xистинно. Такое поведение соответствует стандарту IEEE 754. -
NoneиNotImplemented— синглтоны. PEP 8 рекомендует всегда сравнивать синглтоны с помощьюisилиis not, а не операторов равенства. - Двоичные последовательности (экземпляры
bytesилиbytearray) можно сравнивать как внутри одного типа, так и между типами. Сравнение выполняется лексикографически с использованием числовых значений элементов. -
Строки (экземпляры
str) сравниваются лексикографически по числовым кодовым точкам Unicode символов (результатам встроенной функцииord()). [3]Строки и двоичные последовательности нельзя сравнивать напрямую.
-
Последовательности (экземпляры
tuple,listилиrange) можно сравнивать только внутри каждого типа; при этом диапазоны не поддерживают сравнение на порядок. Сравнение на равенство объектов разных типов даёт неравенство, а сравнение на порядок объектов разных типов вызывает исключениеTypeError.Последовательности сравниваются лексикографически, путём сравнения соответствующих элементов. Встроенные контейнеры обычно считают, что идентичные объекты равны сами себе. Это позволяет им пропускать проверки на равенство идентичных объектов, повышая производительность и сохраняя внутренние инварианты.
Лексикографическое сравнение встроенных коллекций выполняется следующим образом:
- Чтобы две коллекции считались равными, они должны иметь одинаковый тип и длину, а каждая пара соответствующих элементов должна быть равна (например,
[1,2] == (1,2)ложно, поскольку типы различаются). - Коллекции, поддерживающие сравнение на порядок, упорядочиваются так же, как их первые неравные элементы (например,
[1,2,x] <= [1,2,y]имеет то же значение, что иx <= y). Если соответствующий элемент отсутствует, первой считается более короткая коллекция (например,[1,2] < [1,2,3]истинно).
- Чтобы две коллекции считались равными, они должны иметь одинаковый тип и длину, а каждая пара соответствующих элементов должна быть равна (например,
-
Сопоставления (экземпляры
dict) равны тогда и только тогда, когда у них совпадают пары(key, value). Сравнение ключей и значений на равенство обеспечивает рефлексивность.Сравнение на порядок (
<,>,<=и>=) вызывает исключениеTypeError. -
Множества (экземпляры
setилиfrozenset) можно сравнивать как внутри одного типа, так и между типами.Операторы сравнения на порядок для множеств означают проверку на подмножество и надмножество. Эти отношения не задают линейный порядок (например, множества
{1,2}и{2,3}не равны, и ни одно из них не является подмножеством или надмножеством другого). Поэтому множества не подходят в качестве аргументов для функций, которым требуется линейный порядок (например,min(),max()иsorted()дают неопределённые результаты, если им передать список множеств).Сравнение множеств обеспечивает рефлексивность их элементов.
- У большинства других встроенных типов методы сравнения не реализованы, поэтому они наследуют поведение сравнения по умолчанию.
Пользовательским классам, настраивающим поведение сравнения, по возможности следует соблюдать некоторые правила согласованности:
-
Сравнение на равенство должно быть рефлексивным. Иными словами, идентичные объекты должны считаться равными:
x is yподразумеваетx == y -
Сравнение должно быть симметричным. Иными словами, следующие выражения должны давать одинаковый результат:
x == yиy == xx != yиy != xx < yиy > xx <= yиy >= x -
Сравнение должно быть транзитивным. Следующие примеры (не исчерпывающий список) иллюстрируют это свойство:
x > y and y > zподразумеваетx > zx < y and y <= zподразумеваетx < z -
Обратное сравнение должно давать логическое отрицание. Иными словами, следующие выражения должны давать одинаковый результат:
x == yиnot x != yx < yиnot x >= y(для линейного порядка)x > yиnot x <= y(для линейного порядка)Последние два выражения относятся к коллекциям с линейным порядком (например, к последовательностям, но не к множествам или сопоставлениям). См. также декоратор
total_ordering(). - Результат
hash()должен согласовываться с равенством. Равные объекты должны либо иметь одинаковое хеш-значение, либо быть помечены как нехешируемые.
Python не обеспечивает соблюдение этих правил согласованности. Значения «не число» служат примером того, как эти правила могут нарушаться.
6.10.2. Операции проверки принадлежности
Операторы in и not in проверяют принадлежность. Выражение x in
s принимает значение True, если x является элементом s, и False в противном случае. Выражение x not in s возвращает логическое отрицание x in s. Все встроенные последовательности и типы множеств поддерживают эту операцию, как и словари, для которых in проверяет, содержит ли словарь заданный ключ. Для контейнерных типов, таких как list, tuple, set, frozenset, dict или collections.deque, выражение x in y эквивалентно any(x is e or x == e for e in y).
Для строк и байтовых последовательностей выражение x in y принимает значение True тогда и только тогда, когда x является подстрокой y. Эквивалентная проверка: y.find(x) != -1. Пустые строки всегда считаются подстроками любой другой строки, поэтому "" in "abc" вернёт True.
Для пользовательских классов, определяющих метод __contains__(), выражение x in
y возвращает True, если y.__contains__(x) возвращает истинное значение, и False в противном случае.
Для пользовательских классов, которые не определяют __contains__(), но определяют __iter__(), выражение x in y принимает значение True, если при переборе y получено некоторое значение z, для которого выражение x is z or x == z истинно. Если во время перебора возникает исключение, считается, что in вызвало это исключение.
Наконец, выполняется попытка использовать старый протокол итерации: если класс определяет __getitem__(), выражение x in y принимает значение True тогда и только тогда, когда существует неотрицательный целочисленный индекс i, для которого выполняется x is y[i] or x == y[i], и ни один меньший целочисленный индекс не вызывает исключение IndexError. (Если возникает любое другое исключение, считается, что in вызвало это исключение.)
Оператор not in определён так, что его логическое значение противоположно логическому значению in.
6.10.3. Сравнения идентичности
Операторы is и is not проверяют идентичность объектов: x
is y истинно тогда и только тогда, когда x и y — один и тот же объект. Идентичность объекта определяется с помощью функции id(). Выражение x is not y возвращает противоположное логическое значение. [4]
6.11. Логические операции
or_test ::= and_test | or_test "or" and_test and_test ::= not_test | and_test "and" not_test not_test ::= comparison | "not" not_test
В контексте логических операций, а также при использовании выражений в операторах управления потоком, следующие значения интерпретируются как ложные: False, None, числовой ноль любого типа, а также пустые строки и контейнеры (включая строки, кортежи, списки, словари, множества и неизменяемые множества). Все остальные значения интерпретируются как истинные. Пользовательские объекты могут настраивать своё логическое значение, предоставив метод __bool__().
Оператор not возвращает True, если его аргумент ложен, и False в противном случае.
Выражение x and y сначала вычисляет x; если x ложно, возвращается его значение; в противном случае вычисляется y и возвращается полученное значение.
Выражение x or y сначала вычисляет x; если x истинно, возвращается его значение; в противном случае вычисляется y и возвращается полученное значение.
Обратите внимание, что ни and, ни or не ограничивают возвращаемое значение и его тип значениями False и True, а возвращают последний вычисленный аргумент. Это иногда бывает полезно: например, если s — строка, которую следует заменить значением по умолчанию, когда она пуста, выражение s or 'foo' возвращает нужное значение. Поскольку not должен создавать новое значение, он возвращает логическое значение независимо от типа своего аргумента (например, not 'foo' возвращает False, а не ''.)
6.12. Выражения присваивания
assignment_expression ::= [identifier ":="] expression
Выражение присваивания (иногда также называемое «именованным выражением» или «моржом») присваивает expression identifier, одновременно возвращая значение expression.
Один из распространённых случаев использования — обработка совпадений с регулярными выражениями:
if matching := pattern.search(data):
do_something(matching)
Другой пример — обработка файлового потока по частям:
while chunk := file.read(9000):
process(chunk)
Выражения присваивания должны быть заключены в круглые скобки, если они используются как операторы-выражения, а также в качестве подвыражений в срезах, условных выражениях, лямбда-выражениях, выражениях с именованными аргументами и выражениях comprehension с условием if, а также в операторах assert, with и assignment. Во всех остальных случаях, где их можно использовать, скобки не требуются, в том числе в операторах if и while.
Добавлено в версии 3.8: Дополнительные сведения о выражениях присваивания см. в PEP 572.
6.13. Условные выражения
conditional_expression ::= or_test ["if" or_test "else" expression] expression ::= conditional_expression | lambda_expr
Условные выражения (иногда называемые «тернарным оператором») имеют наименьший приоритет среди всех операций Python.
Выражение x if C else y сначала вычисляет условие C, а не x. Если C истинно, вычисляется x и возвращается его значение; в противном случае вычисляется y и возвращается его значение.
Дополнительные сведения об условных выражениях см. в PEP 308.
6.14. Лямбда-выражения
lambda_expr ::= "lambda" [parameter_list] ":" expression
Лямбда-выражения (иногда называемые лямбда-формами) используются для создания анонимных функций. Выражение lambda parameters: expression возвращает объект-функцию. Этот безымянный объект ведёт себя как объект-функция, определённый с помощью:
def <lambda>(parameters):
return expression
Синтаксис списков параметров описан в разделе Определения функций. Обратите внимание, что функции, созданные с помощью лямбда-выражений, не могут содержать операторы или аннотации.
6.15. Списки выражений
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.
Завершающая запятая требуется только для создания кортежа из одного элемента, например 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.11/reference/expressions.html