Выражения
В этой главе объясняется значение элементов выражений в Python.
Примечания по синтаксису: В этой и последующих главах будет использоваться расширенная нотация BNF для описания синтаксиса, а не лексического анализа. Когда (одна альтернатива) правило синтаксиса имеет вид
name ::= othername
и семантика не приводится, семантика этой формы name такая же, как и для othername.
6.1. Арифметические преобразования
Когда в описании арифметического оператора ниже используется фраза «численные аргументы преобразуются к общему типу», это означает, что реализация оператора для встроенных типов работает следующим образом:
- Если какой-либо аргумент является комплексным числом, другой преобразуется к комплексному;
- в противном случае, если какой-либо аргумент является числом с плавающей точкой, другой преобразуется к числу с плавающей точкой;
- в противном случае оба аргумента должны быть целыми числами и преобразование не требуется.
Для некоторых операторов (например, строка как левый аргумент оператора '%') применяются дополнительные правила. Расширения должны определить собственное поведение преобразования.
6.2. Атомы
Атомы — это наиболее базовые элементы выражений. Простейшие атомы — это идентификаторы или литералы. Формы, заключённые в скобки, квадратные скобки или фигурные скобки, также синтаксически классифицируются как атомы. Синтаксис атомов:
atom ::= identifier | literal | enclosure
enclosure ::= parenth_form | list_display | dict_display | set_display
| generator_expression | yield_atom
6.2.1. Идентификаторы (Имена)
Идентификатор, встречающийся как атом, является именем. См. раздел Идентификаторы и ключевые слова для лексического определения и раздел Именование и привязка для документации именования и привязки.
Когда имя привязано к объекту, вычисление атома возвращает этот объект. Когда имя не привязано, попытка вычислить его вызывает исключение NameError.
Присвоение имени: Когда идентификатор, который текстово встречается в определении класса, начинается с двух или более символов нижнего подчеркивания и не заканчивается двумя или более символами нижнего подчеркивания, он считается приватным именем этого класса. Приватные имена преобразуются в более длинную форму перед генерацией кода для них. Преобразование вставляет имя класса, из которого удалены ведущие символы нижнего подчеркивания и добавлен одиночный символ нижнего подчеркивания, перед именем. Например, идентификатор __spam , встречающийся в классе с именем Ham , будет преобразован в _Ham__spam. Это преобразование независимо от синтаксического контекста использования идентификатора. Если преобразованное имя слишком длинное (длиннее 255 символов), может произойти реализационно-зависимое усечение. Если имя класса состоит только из символов нижнего подчеркивания, преобразование не выполняется.
6.2.2. Литералы
Python поддерживает строковые и байтовые литералы, а также различные числовые литералы:
literal ::= stringliteral | bytesliteral
| integer | floatnumber | imagnumber
Вычисление литерала возвращает объект указанного типа (строка, байты, целое число, число с плавающей точкой, комплексное число) с заданным значением. Значение может быть приблизительно в случае литералов с плавающей точкой и мнимой (комплексной) частью. Подробности см. в разделе Литералы.
Все литералы соответствуют неизменяемым типам данных, и поэтому идентичность объекта менее важна, чем его значение. При нескольких вычислениях литералов с одинаковым значением (либо одинаковое в тексте программы, либо разное) может быть получен один и тот же объект или другой объект с тем же значением.
6.2.3. Формы в скобках
Форма в скобках — это необязательный список выражений, заключенный в круглые скобки:
parenth_form ::= "(" [starred_expression] ")"
Список выражений в скобках возвращает то, что возвращает этот список выражений: если список содержит по крайней мере одну запятую, он возвращает кортеж; в противном случае, он возвращает единственное выражение, составляющее список выражений.
Пустая пара скобок возвращает пустой объект кортежа. Поскольку кортежи неизменяемы, применяются те же правила, что и для литералов (то есть два появления пустого кортежа могут или не могут возвращать один и тот же объект).
Обратите внимание, что кортежи не образуются скобками, а скорее оператором запятой. Исключение составляет пустой кортеж, для которого скобки требуются — без скобок «ничего» в выражениях привело бы к неоднозначностям и позволило бы пропустить общие опечатки.
6.2.4. Представления для списков, множеств и словарей
Для создания списка, множества или словаря Python предоставляет специальный синтаксис, называемый «представлениями», каждый из которых существует в двух вариантах:
- либо содержимое контейнера перечисляется явно, или
- они вычисляются с помощью набора инструкций циклирования и фильтрации, называемых генератором.
Общие синтаксические элементы для генераторов:
comprehension ::= assignment_expression comp_for comp_for ::= ["async"] "for" target_list "in" or_test [comp_iter] comp_iter ::= comp_for | comp_if comp_if ::= "if" or_test [comp_iter]
Генератор состоит из одного выражения, за которым следуют по крайней мере одна for-строка и ноль или более for или if-строки. В этом случае элементами нового контейнера являются те, которые были бы получены при рассмотрении каждой из for или if-строк как блока, вложенных слева направо, и вычислении выражения для получения элемента каждый раз, когда достигается самый внутренний блок.
Однако, за исключением выражения итерируемого объекта в самой левой for-строке, генератор выполняется в отдельном неявно вложенном пространстве имён. Это гарантирует, что имена, присвоенные в целевом списке, не «просачиваются» в окружающее пространство имён.
Выражение итерируемого объекта в самой левой for-строке вычисляется непосредственно в окружающем пространстве имён и затем передаётся в качестве аргумента неявно вложенному пространству имён. Последующие for-строки и любые условия фильтрации в самой левой for-строке не могут быть вычислены в окружающем пространстве имён, так как они могут зависеть от значений, полученных из самой левой итерируемой части. Например: [x*y for x in range(10) for y in range(x, x+10)].
Для обеспечения того, чтобы генератор всегда возвращал контейнер соответствующего типа, yield и yield from-выражения запрещены в неявно вложенном пространстве имён.
Начиная с Python 3.6, в асинхронной функции async def, может быть использована async for-строка для итерирования по асинхронному итератору асинхронному итератору. Генератор в асинхронной async def-функции может состоять либо из for-строки, либо из async for-строки, следующей за ведущим выражением, может содержать дополнительные for или async for-строки и также может использовать await выражения. Если генератор содержит либо async for-строки, либо await-выражения, он называется асинхронным генератором. Асинхронный генератор может приостанавливать выполнение функции корутины, в которой он появляется. См. также PEP 530.
New in version 3.6: Асинхронные генераторы.
Changed in version 3.8: yield и yield from запрещены в неявно вложенном пространстве имён.
6.2.5. Представления списков
Представление списка — это, возможно, пустая последовательность выражений, заключённых в квадратные скобки:
list_display ::= "[" [starred_list | comprehension] "]"
Представление списка возвращает новый объект списка, содержимое которого определяется либо списком выражений, либо генератором. Когда предоставлен список выражений, разделённых запятыми, его элементы вычисляются слева направо и помещаются в объект списка в этом порядке. Когда предоставлен генератор, список создаётся из элементов, полученных в результате генератора.
6.2.6. Представления множеств
Представление множества обозначается фигурными скобками и отличается от представлений словарей отсутствием двоеточий, разделяющих ключи и значения:
set_display ::= "{" (starred_list | comprehension) "}"
Представление множества возвращает новый изменяемый объект множества, содержимое которого определяется либо последовательностью выражений, либо генератором. Когда предоставлен список выражений, разделённых запятыми, его элементы вычисляются слева направо и добавляются к объекту множества. Когда предоставлен генератор, множество создаётся из элементов, полученных в результате генератора.
Пустое множество не может быть создано с помощью {}; этот литерал создаёт пустой словарь.
6.2.7. Представления словарей
Представление словаря — это, возможно, пустая последовательность пар ключ/значение, заключённых в фигурные скобки:
dict_display ::= "{" [key_datum_list | dict_comprehension] "}"
key_datum_list ::= key_datum ("," key_datum)* [","]
key_datum ::= expression ":" expression | "**" or_expr
dict_comprehension ::= expression ":" expression comp_for
Представление словаря возвращает новый объект словаря.
Если предоставлена последовательность пар ключ/значение, разделённых запятыми, они вычисляются слева направо, чтобы определить записи словаря: каждый объект ключа используется в качестве ключа в словаре для хранения соответствующего значения. Это означает, что вы можете несколько раз указать один и тот же ключ в списке ключ/значение, и конечное значение словаря для этого ключа будет последним заданным.
Двойная звёздочка ** обозначает распаковку словаря. Его операнд должен быть отображением отображением. Каждый элемент отображения добавляется в новый словарь. Позже значения заменяют значения, уже установленные предыдущими парами ключ/значение и предыдущими распаковками словарей.
New in version 3.5: Распаковка в представления словарей, первоначально предложенная PEP 448.
Генератор словаря, в отличие от генераторов списков и множеств, требует двух выражений, разделённых двоеточием, за которыми следуют обычные фразы «for» и «if». При выполнении генератора результирующие элементы ключа и значения вставляются в новый словарь в порядке их получения.
Ограничения на типы значений ключей приведены ранее в разделе Стандартная иерархия типов. (Подводя итог, тип ключа должен быть хешируемым, что исключает все изменяемые объекты). Конфликты между повторяющимися ключами не обнаруживаются; последнее значение (текстово последнее в представлении) хранимое для данного значения ключа преобладает.
Changed in version 3.8: До Python 3.8 в генераторах словарей порядок вычисления ключа и значения не был определён. В CPython значение вычислялось до ключа. Начиная с 3.8, ключ вычисляется перед значением, как предложено в PEP 572.
6.2.8. Генераторные выражения
Генераторное выражение — это компактная запись генератора в скобках:
generator_expression ::= "(" expression comp_for ")"
Генераторное выражение возвращает новый объект генератора. Его синтаксис такой же, как у выражений-генераторов, за исключением того, что оно заключено в скобки вместо квадратных скобок или фигурных скобок.
Переменные, используемые в генераторном выражении, вычисляются лениво, когда для объекта генератора вызывается метод __next__() (так же, как и обычные генераторы). Однако выражение итерируемого объекта в левой for части сразу же вычисляется, поэтому ошибка, сгенерированная им, будет выдана в тот момент, когда определяется генераторное выражение, а не в тот момент, когда извлекается первое значение. Последующие for части и любой фильтр в самой левой for части нельзя вычислить в окружающем объёме, так как они могут зависеть от значений, полученных из самого левого итерируемого объекта. Например: (x*y for x in range(10) for y in range(x, x+10)).
Скобки можно опустить при вызовах с одним аргументом. Подробности см. в разделе Вызовы.
Для предотвращения вмешательства в ожидаемую работу самого генераторного выражения, yield и yield from выражения запрещены в неявном генераторе.
Если генераторное выражение содержит либо async for части, либо выражения await, оно называется асинхронным генераторным выражением. Асинхронное генераторное выражение возвращает новый объект асинхронного генератора, который является асинхронным итератором (см. Асинхронные итераторы).
Добавлено в версии 3.6: Асинхронные генераторные выражения.
Изменено в версии 3.7: До Python 3.7 асинхронные генераторные выражения могли использоваться только в async def корутинах. Начиная с версии 3.7, асинхронные генераторные выражения может использовать любая функция.
Изменено в версии 3.8: yield и yield from запрещены во вложенном объёме.
6.2.9. Выражения yield
yield_atom ::= "(" yield_expression ")"
yield_expression ::= "yield" [expression_list | "from" expression]
Выражение yield используется при определении функции-генератора или функции-асинхронного генератора, и поэтому может использоваться только в теле определения функции. Использование выражения yield в теле функции делает эту функцию функцией-генератором, а его использование в теле async def функции делает эту корутинную функцию функцией-асинхронного генератора. Например:
def gen(): # defines a generator function
yield 123
async def agen(): # defines an asynchronous generator function
yield 123
Из-за их побочных эффектов на окружающую область, yield выражения запрещены в неявных объёмах, используемых для реализации выражений-генераторов и списковых включений.
Изменено в версии 3.8: Выражения yield запрещены во вложенных объёмах, используемых для реализации списковых включений и генераторных выражений.
Функции-генераторы описаны ниже, в то время как функции-асинхронные генераторы описаны отдельно в разделе Функции-асинхронные генераторы.
При вызове функции-генератора она возвращает итератор, известный как генератор. Этот генератор затем контролирует выполнение функции-генератора. Выполнение начинается, когда вызывается один из методов генератора. В этот момент выполнение переходит к первому выражению yield, где оно приостанавливается снова, возвращая значение expression_list вызывающему генератор, или 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.
Вызов одного из методов асинхронного генератора возвращает объект awaitable, и выполнение начинается при ожидании этого объекта. В этот момент выполнение переходит к первому выражению yield, где оно снова приостанавливается, возвращая значение expression_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__() -
Возвращает ожидаемый результат, который при выполнении запускает асинхронный генератор или возобновляет его в последней выполненной выражении 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) -
coroutine agen.athrow(type[, value[, traceback]]) -
Возвращает ожидаемый результат, который поднимает исключение типа
typeв тот момент, когда асинхронный генератор был приостановлен, и возвращает следующее значение, сгенерированное функцией-генератором, как значение поднятого исключенияStopIteration. Если асинхронный генератор завершается без возврата другого значения, поднимается исключениеStopAsyncIteration. Если функция-генератор не перехватывает переданное исключение или поднимает другое исключение, то при выполнении ожидаемого результата это исключение передаётся вызывающей стороне ожидаемого результата.
-
coroutine agen.aclose() -
Возвращает ожидаемый результат, который при выполнении вызовет
GeneratorExitв функции асинхронного генератора в тот момент, когда она была приостановлена. Если функция асинхронного генератора затем завершается корректно, уже закрыта или поднимаетGeneratorExit(не перехватив исключение), тогда возвращаемый ожидаемый результат поднимет исключениеStopIteration. Любые дальнейшие ожидаемые результаты, возвращаемые последующими вызовами асинхронного генератора, поднимут исключениеStopAsyncIteration. Если асинхронный генератор возвращает значение, ожидаемый результат подниметRuntimeError. Если асинхронный генератор поднимет любое другое исключение, оно передаётся вызывающей стороне ожидаемого результата. Если асинхронный генератор уже завершился из-за исключения или нормального завершения, дальнейшие вызовыaclose()вернут ожидаемый результат, который ничего не делает.
6.3. Основные элементы
Основные элементы представляют собой наиболее тесно связанные операции языка. Их синтаксис:
primary ::= atom | attributeref | subscription | slicing | call
6.3.1. Ссылки на атрибуты
Ссылка на атрибут — это основной элемент, за которым следует точка и имя:
attributeref ::= primary "." identifier
Основной элемент должен быть объектом типа, поддерживающего ссылки на атрибуты, что характерно для большинства объектов. Затем этому объекту задаётся вопрос о получении атрибута, имя которого соответствует идентификатору. Этот процесс можно настроить, переопределив метод __getattr__(). Если этот атрибут недоступен, возникает исключение AttributeError. В противном случае тип и значение полученного объекта определяются объектом. Несколько вычислений одной и той же ссылки на атрибут могут привести к различным объектам.
6.3.2. Подписка
Подписка на экземпляр класса контейнера обычно выбирает элемент из контейнера. Подписка на обобщённый класс обычно возвращает объект GenericAlias.
subscription ::= primary "[" expression_list "]"
При подписке на объект интерпретатор вычислит основной элемент и список выражений.
Основной элемент должен быть объектом, поддерживающим подписку. Объект может поддерживать подписку, определив один или оба из методов __getitem__() и __class_getitem__(). При подписке на основной элемент вычисленное значение списка выражений будет передано одному из этих методов. Более подробную информацию о том, когда вызывается __class_getitem__, а не __getitem__, см. в разделе __class_getitem__ против __getitem__.
Если список выражений содержит по крайней мере одну запятую, он будет вычисляться как кортеж tuple, содержащий элементы списка выражений. В противном случае, список выражений будет вычисляться как значение единственного его элемента.
Для встроенных объектов существуют два типа объектов, которые поддерживают подписку через __getitem__():
- Карты. Если основной элемент является отображением, список выражений должен вычисляться как объект, значение которого является одним из ключей отображения, и подписка выбирает значение в отображении, соответствующее этому ключу. Примером встроенного класса отображения является класс
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() при вызове с двумя аргументами: возвращает левое значение, возведенное в степень правого. Числовые аргументы сначала преобразуются в общий тип, и результат имеет этот тип.
Для целочисленных операндов результат имеет тот же тип, что и операнды, за исключением случаев, когда второй аргумент отрицательный; в этом случае все аргументы преобразуются в тип 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__().
Оператор % (modulo) возвращает остаток от деления первого аргумента на второй. Числовые аргументы сначала преобразуются к общему типу. Нулевой правый аргумент вызывает исключение ZeroDivisionError. Аргументы могут быть числами с плавающей точкой, например, 3.14%0.7 равно 0.34 (так как 3.14 равно 4*0.7 + 0.34.) Оператор modulo всегда возвращает результат со знаком второго операнда (или ноль); абсолютное значение результата строго меньше абсолютного значения второго операнда 1.
Операторы целочисленного деления и modulo связаны следующим тождеством: x == (x//y)*y + (x%y). Операторы целочисленного деления и modulo также связаны с встроенной функцией divmod(): divmod(x, y) == (x//y,
x%y). 2.
Помимо выполнения операции modulo над числами, оператор % также перегружен для строковых объектов, чтобы выполнить форматирование строк старого стиля (также известное как интерполяция). Синтаксис форматирования строк описан в Справочнике по библиотеке Python, раздел Форматирование строк в стиле printf.
Операцию modulo можно настроить с помощью метода __mod__().
Оператор целочисленного деления, оператор modulo и функция divmod() не определены для комплексных чисел. Вместо этого, преобразуйте в число с плавающей точкой, используя функцию abs(), если это необходимо.
Оператор + (сложение) возвращает сумму своих аргументов. Аргументы должны быть либо оба числами, либо обе последовательностями одного типа. В первом случае числа преобразуются к общему типу и затем складываются. Во втором случае последовательности конкатенируются.
Эту операцию можно настроить с помощью специальных методов __add__() и __radd__().
Оператор - (вычитание) возвращает разность своих аргументов. Числовые аргументы сначала преобразуются к общему типу.
Эту операцию можно настроить с помощью специального метода __sub__().
6.8. Операции сдвига
Операции сдвига имеют более низкий приоритет, чем арифметические операции:
shift_expr ::= a_expr | shift_expr ("<<" | ">>") a_expr
Эти операторы принимают целые числа в качестве аргументов. Они сдвигают первый аргумент влево или вправо на количество бит, заданное вторым аргументом.
Эту операцию можно настроить с помощью специальных методов __lshift__() и __rshift__().
Сдвиг вправо на n бит определяется как целочисленное деление на pow(2,n). Сдвиг влево на n бит определяется как умножение на pow(2,n).
6.9. Бинарные побитовые операции
Каждая из трёх побитовых операций имеет свой уровень приоритета:
and_expr ::= shift_expr | and_expr "&" shift_expr xor_expr ::= and_expr | xor_expr "^" and_expr or_expr ::= xor_expr | or_expr "|" xor_expr
Оператор & возвращает побитовое И своих аргументов, которые должны быть целыми числами, или один из них должен быть пользовательским объектом, переопределяющим __and__() или __rand__() специальные методы.
Оператор ^ возвращает побитовое ИСКЛЮЧАЮЩЕЕ ИЛИ (XOR) своих аргументов, которые должны быть целыми числами, или один из них должен быть пользовательским объектом, переопределяющим __xor__() или __rxor__() специальные методы.
Оператор | возвращает побитовое ИЛИ своих аргументов, которые должны быть целыми числами, или один из них должен быть пользовательским объектом, переопределяющим __or__() или __ror__() специальные методы.
6.10. Сравнения
В отличие от C, все операции сравнения в Python имеют одинаковый приоритет, который ниже приоритета любых арифметических, сдвиговых или побитовых операций. Также в отличие от C, выражения, такие как a < b < c , интерпретируются так, как это принято в математике:
comparison ::= or_expr (comp_operator or_expr)*
comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="
| "is" ["not"] | ["not"] "in"
Сравнения возвращают булевы значения: True или False. Пользовательские методы богатых сравнений могут возвращать значения, отличные от булевых. В этом случае Python вызовет bool() для таких значений в контексте булевых операций.
Сравнения можно произвольно цеплять, например, x < y <= z эквивалентно x < y and y <= z, за исключением того, что y вычисляется только один раз (но в обоих случаях z не вычисляется вообще, когда x < y оказывается ложным).
Формально, если a, b, c, …, y, z — выражения, а op1, op2, …, opN — операторы сравнения, то a op1 b op2 c ... y opN z эквивалентно a op1 b and b op2 c and ... y opN z, за исключением того, что каждое выражение вычисляется не более одного раза.
Обратите внимание, что a op1 b op2 c не подразумевает никакого сравнения между a и c, так что, например, x < y > z совершенно законно (хотя, возможно, и не очень красиво).
6.10.1. Сравнение значений
Операторы <, >, ==, >=, <=, и != сравнивают значения двух объектов. Объекты не обязательно должны иметь одинаковый тип.
В главе Объекты, значения и типы говорится, что объекты имеют значение (кроме типа и идентификатора). Значение объекта — довольно абстрактное понятие в Python: например, нет канонического способа доступа к значению объекта. Кроме того, нет требования, чтобы значение объекта строилось определенным образом, например, на основе всех его атрибутов данных. Операторы сравнения реализуют определенное понятие значения объекта. Можно считать, что они определяют значение объекта косвенно, посредством своей реализации сравнения.
Поскольку все типы являются (прямыми или косвенными) подтипами object, они наследуют поведение по умолчанию для сравнения от object. Типы могут настраивать свое поведение при сравнении, реализуя методы богатых сравнений, такие как __lt__(), описанные в Основные настройки.
Поведение по умолчанию для сравнения на равенство (== и != ) основано на идентификаторе объектов. Таким образом, сравнение на равенство экземпляров с одинаковым идентификатором даёт результат равенства, а сравнение на равенство экземпляров с разными идентификаторами даёт результат неравенства. Цель такого поведения по умолчанию — обеспечить, чтобы все объекты были рефлексивными (т. е. x is y подразумевает x == y).
Поведение по умолчанию для сравнения по порядку (<, >, <=, и >=) не предоставляется; попытка вызвать его вызовет TypeError. Причина такого поведения по умолчанию заключается в отсутствии аналогичного инварианта, как для равенства.
Поведение по умолчанию для сравнения на равенство, что экземпляры с разными идентификаторами всегда не равны, может противоречить тому, что типы нуждаются в разумном определении значения объекта и равенства на основе значения. Такие типы должны настраивать свое поведение при сравнении, и на самом деле ряд встроенных типов это сделали.
В следующем списке описано поведение сравнения наиболее важных встроенных типов.
-
Числа встроенных числовых типов (Числовые типы — int, float, complex) и типов стандартной библиотеки
fractions.Fractionиdecimal.Decimalмогут сравниваться внутри и между своими типами, с ограничением, что комплексные числа не поддерживают сравнение по порядку. В пределах участвующих типов они сравниваются математически (алгоритмически) корректно без потерь точности.Значения не-числа
float('NaN')иdecimal.Decimal('NaN')являются специальными. Любое упорядоченное сравнение числа с не-числовым значением ложно. Противоинтуитивное следствие заключается в том, что значения не-чисел не равны самим себе. Например, еслиx = float('NaN'),3 < x,x < 3иx == xвсе ложны, аx != xистинно. Это поведение соответствует IEEE 754. -
NoneиNotImplemented— это одиночные объекты. PEP 8 рекомендует, что сравнения для одиночных объектов всегда должны выполняться с помощьюisилиis not, а не операторов равенства. - Двоичные последовательности (экземпляры
bytesилиbytearray) можно сравнивать внутри и между своими типами. Они сравниваются лексикографически с использованием числовых значений своих элементов. -
Строки (экземпляры
str) сравниваются лексикографически с использованием числовых кодовых точек Unicode (результат встроенной функцииord()) их символов. 3Строки и двоичные последовательности не могут быть напрямую сравнены.
-
Последовательности (экземпляры
tuple,listилиrange) могут сравниваться только внутри каждого из своих типов, с ограничением, что диапазоны не поддерживают сравнение по порядку. Сравнение на равенство между этими типами приводит к неравенству, а сравнение по порядку между этими типами вызываетTypeError.Последовательности сравниваются лексикографически с помощью сравнения соответствующих элементов. Встроенные контейнеры, как правило, предполагают, что идентичные объекты равны самим себе. Это позволяет им обойти проверки на равенство для идентичных объектов, чтобы повысить производительность и сохранить свои внутренние инварианты.
Лексикографическое сравнение встроенных коллекций выполняется следующим образом:
- Для сравнения двух коллекций на равенство они должны быть одного типа, иметь одинаковую длину, и каждая пара соответствующих элементов должна сравниваться как равные (например,
[1,2] == (1,2)ложно, потому что тип не тот же). - Коллекции, которые поддерживают сравнение по порядку, упорядочиваются так же, как и их первые неравные элементы (например,
[1,2,x] <= [1,2,y]имеет то же значение, что иx <= y). Если соответствующий элемент не существует, короче коллекция упорядочивается первой (например,[1,2] < [1,2,3]истинно).
- Для сравнения двух коллекций на равенство они должны быть одного типа, иметь одинаковую длину, и каждая пара соответствующих элементов должна сравниваться как равные (например,
-
Отображения (экземпляры
dict) сравниваются как равные только в том случае, если они имеют равные пары(key, value). Сравнение на равенство ключей и значений обеспечивает рефлексивность.Сравнения по порядку (
<,>,<=, и>=) вызываютTypeError. -
Множества (экземпляры
setилиfrozenset) можно сравнивать внутри и между своими типами.Они определяют операторы сравнения по порядку, которые означают проверки подмножества и надмножества. Эти отношения не определяют полные порядки (например, два множества
{1,2}и{2,3}не равны, не являются подмножествами друг друга и не являются надмножествами друг друга). Соответственно, множества не являются подходящими аргументами для функций, которые зависят от полного порядка (например,min(),max()иsorted()дают неопределенные результаты при вводе списка множеств).Сравнение множеств обеспечивает рефлексивность его элементов.
- Большинство других встроенных типов не имеют реализованных методов сравнения, поэтому они наследуют поведение сравнения по умолчанию.
Пользовательские классы, которые настраивают свое поведение при сравнении, должны придерживаться определенных правил согласованности, если это возможно:
-
Сравнение на равенство должно быть рефлексивным. Другими словами, идентичные объекты должны сравниваться как равные:
x is yподразумеваетx == y -
Сравнение должно быть симметричным. Другими словами, следующие выражения должны давать одинаковый результат:
x == yиy == 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 если какое-то значение z, для которого выражение x is z or x == z истинно, генерируется при итерировании по y. Если во время итерирования возникает исключение, это как если бы in вызвало это исключение.
Наконец, пробуется протокол итерации старого стиля: если класс определяет __getitem__(), x in y является True тогда и только тогда, когда существует неотрицательный целочисленный индекс i такой, что x is y[i] or x == y[i], и ни один меньший целочисленный индекс не вызывает исключение IndexError. (Если возникает любое другое исключение, это как если бы in вызвало это исключение).
Оператор not in определён как имеющий обратное логическое значение in.
6.10.3. Сравнения по идентичности
Операторы is и is not проверяют идентичность объекта: x
is y истинно тогда и только тогда, когда x и y — один и тот же объект. Идентичность объекта определяется с помощью функции id(). x is not y даёт обратное логическое значение. 4
6.11. Булевы операции
or_test ::= and_test | or_test "or" and_test and_test ::= not_test | and_test "and" not_test not_test ::= comparison | "not" not_test
В контексте булевых операций, а также когда выражения используются в операторах управления потоком, следующие значения интерпретируются как ложные: False, None, числовой ноль всех типов, и пустые строки и контейнеры (включая строки, кортежи, списки, словари, множества и неизменяемые множества). Все остальные значения интерпретируются как истинные. Пользовательские объекты могут настроить своё истинностное значение, предоставив метод __bool__().
Оператор not возвращает True если его аргумент ложный, False в противном случае.
Выражение x and y сначала вычисляет x; если x ложно, возвращается его значение; в противном случае вычисляется y и возвращается полученное значение.
Выражение x or y сначала вычисляет x; если x истинно, возвращается его значение; в противном случае вычисляется y и возвращается полученное значение.
Обратите внимание, что ни and, ни or не ограничивают возвращаемое значение и тип до False и True, а скорее возвращают последний вычисленный аргумент. Это иногда полезно, например, если s — это строка, которая должна быть заменена на значение по умолчанию, если она пустая, выражение s or 'foo' возвращает желаемое значение. Поскольку not должен создать новое значение, он возвращает булево значение независимо от типа своего аргумента (например, not 'foo' производит False вместо ''.)
6.12. Выражения присваивания
assignment_expression ::= [identifier ":="] expression
Выражение присваивания (иногда также называемое «выражение с именем» или «walrus») присваивает expression identifier, одновременно возвращая значение expression.
Один из распространённых случаев использования — обработка совпадений регулярных выражений:
if matching := pattern.search(data):
do_something(matching)
Или, при обработке потока файла частями:
while chunk := file.read(9000):
process(chunk)
Выражения присваивания должны быть заключены в скобки, когда используются как подвыражения в срезах, условных выражениях, лямбда-выражениях, аргументах ключевых слов и выражениях со списками с условной частью, и в assert и with утверждениях. Во всех остальных местах, где они могут быть использованы, скобки не требуются, включая if и while утверждения.
New in version 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
За исключением случаев, когда это часть отображения списков или множеств, список выражений, содержащий по крайней мере одну запятую, возвращает кортеж. Длина кортежа равна количеству выражений в списке. Выражения вычисляются слева направо.
Звёздочка * обозначает распаковку итерируемых. Её операнд должен быть итерируемым. Итерируемый преобразуется в последовательность элементов, которые включаются в новый кортеж, список или множество на месте распаковки.
New in version 3.5: Распаковка итерируемых в списках выражений, первоначально предложенная PEP 448.
Конечная запятая необходима только для создания одного кортежа (также известного как одиночный); она необязательна во всех остальных случаях. Одно выражение без конечной запятой не создаёт кортеж, а скорее возвращает значение этого выражения. (Чтобы создать пустой кортеж, используйте пустую пару скобок: ().)
6.16. Порядок вычисления
Python вычисляет выражения слева направо. Обратите внимание, что при вычислении присваивания правая часть вычисляется до левой.
В следующих строках выражения будут вычислены в арифметическом порядке их постфиксов:
expr1, expr2, expr3, expr4
(expr1, expr2, expr3, expr4)
{expr1: expr2, expr3: expr4}
expr1 + expr2 * (expr3 - expr4)
expr1(expr2, expr3, *expr4, **expr5)
expr3, expr4 = expr1, expr2
6.17. Приоритет операторов
В следующей таблице суммируется приоритет операторов в Python, от наивысшего (самое сильное связывание) до наименьшего (наименее сильное связывание). Операторы в одной ячейке имеют одинаковый приоритет. Если синтаксис не указан явно, операторы являются бинарными. Операторы в одной ячейке группируются слева направо (за исключением возведения в степень, которое группируется справа налево).
Обратите внимание, что сравнения, проверки на членство и проверки тождества имеют одинаковый приоритет и обладают функцией цепочки слева направо, как описано в разделе Сравнения.
Оператор | Описание |
|---|---|
|
| Связывание или выражение в скобках, список, отображение словаря, отображение множества |
| Индексация, срезы, вызов, ссылка на атрибут |
Выражение await | |
| Возведение в степень 5 |
| Положительное, отрицательное, побитовое НЕ |
| Умножение, матричное умножение, деление, целочисленное деление, остаток от деления 6 |
| Сложение и вычитание |
| Сдвиги |
| Побитовое И |
| Побитовое Исключающее ИЛИ |
| Побитовое ИЛИ |
Сравнения, включая проверки на членство и проверки тождества | |
Логическое НЕ | |
Логическое И | |
Логическое ИЛИ | |
| Условное выражение |
Выражение lambda | |
| Выражение присваивания |
Примечания
-
1 -
Хотя
abs(x%y) < abs(y)математически верно, для чисел с плавающей точкой это может быть неверно численно из-за округления. Например, и предполагая платформу, на которой Python float является числом двойной точности IEEE 754, для того чтобы-1e-100 % 1e100имело тот же знак, что и1e100, вычисленное значение равно-1e-100 + 1e100, что численно точно равно1e100. Функцияmath.fmod()возвращает результат, знак которого соответствует знаку первого аргумента, и поэтому возвращает-1e-100в этом случае. Какой подход более подходит, зависит от приложения. -
2 -
Если x очень близок к точному целочисленному кратному y, возможно,
x//yбудет на единицу больше, чем(x-x%y)//yиз-за округления. В таких случаях Python возвращает последнее значение, чтобы сохранить, чтоdivmod(x,y)[0] * y + x % yочень близко кx. -
3 -
Стандарт Unicode различает кодовые точки (например, U+0041) и абстрактные символы (например, «ЛАТИНСКАЯ ПРОПИСНАЯ БУКВА A»). Хотя большинство абстрактных символов в Unicode представлены только одной кодовой точкой, существует ряд абстрактных символов, которые дополнительно могут быть представлены последовательностью более чем одной кодовой точки. Например, абстрактный символ «ЛАТИНСКАЯ ПРОПИСНАЯ БУКВА C С ЦЕДИЛЬЮ» может быть представлен одним прекомпонованным символом в позиции кода U+00C7 или как последовательность базового символа в позиции кода U+0043 (ЛАТИНСКАЯ ПРОПИСНАЯ БУКВА C), за которым следует комбинирующий символ в позиции кода U+0327 (КОМБИНИРУЮЩАЯ ЦЕДИЛЬЯ).
Операторы сравнения для строк сравнивают кодовые точки Unicode. Это может быть неинтуитивно для человека. Например,
"\u00C7" == "\u0043\u0327"этоFalse, даже если обе строки представляют один и тот же абстрактный символ «ЛАТИНСКАЯ ПРОПИСНАЯ БУКВА C С ЦЕДИЛЬЮ».Чтобы сравнивать строки на уровне абстрактных символов (то есть интуитивно для человека), используйте
unicodedata.normalize(). -
4 -
Из-за автоматического сбора мусора, списков освобождения и динамического характера дескрипторов, вы можете заметить, по-видимому, необычное поведение в некоторых случаях использования оператора
is, например, в сравнениях между методами экземпляра или константами. Проверьте их документацию для получения дополнительной информации. -
5 -
Оператор возведения в степень
**связывается слабее, чем арифметический или побитовый унарный оператор справа, то есть2**-1это0.5. -
6 -
Оператор
%также используется для форматирования строк; тот же приоритет применяется.
© 2001–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.10/reference/expressions.html