Выражения
В этой главе объясняется значение элементов выражений в 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.
New in version 3.6: Асинхронные генераторы были введены.
Changed in version 3.8: yield и yield from запрещены в неявно вложенном пространстве имен.
Changed in version 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_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; управление всегда передаётся вызывающей стороне генератора.
Выражения 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) - 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
Первичное выражение должно оцениваться как объект типа, поддерживающего обращения к атрибутам, что характерно для большинства объектов. Затем этому объекту задается запрос на получение атрибута с указанным именем. Тип и значение, возвращаемые объектом, определяются им. Несколько оценок одного и того же обращения к атрибуту могут возвращать разные объекты.
Это поведение можно настроить, переопределив метод __getattribute__() или метод __getattr__(). Метод __getattribute__() вызывается первым и возвращает значение или генерирует исключение AttributeError, если атрибут недоступен.
Если генерируется исключение AttributeError и у объекта есть метод __getattr__(), этот метод вызывается в качестве резервного варианта.
6.3.2. Обращения по индексу
Обращение по индексу к экземпляру класса контейнера обычно выбирает элемент из контейнера. Обращение по индексу к экземпляру обобщённого класса обычно возвращает объект GenericAlias.
subscription ::= primary "[" expression_list "]"
При обращении к объекту по индексу интерпретатор вычисляет первичное выражение и список выражений.
Первичное выражение должно быть объектом, поддерживающим обращение по индексу. Объект может поддерживать обращение по индексу, определив один или оба метода __getitem__() и __class_getitem__(). При обращении к первичному выражению, вычисленное значение списка выражений будет передано в один из этих методов. Более подробную информацию о том, когда вызывается __class_getitem__, а не __getitem__, см. в разделе __class_getitem__ против __getitem__.
Если список выражений содержит хотя бы одну запятую, он будет вычислен как кортеж, содержащий элементы списка выражений. В противном случае, список выражений будет вычислен как значение его единственного элемента.
Для встроенных объектов существуют два типа объектов, поддерживающих обращение по индексу через метод __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
Приостанавливает выполнение генератора на объекте awaitable. Может использоваться только внутри функции генератора.
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__().
Оператор @ (@) предназначен для использования в матричном умножении. Ни один встроенный тип Python не реализует этот оператор.
Новое в версии 3.5.
Операторы / (деление) и // (деление с отбрасыванием дробной части) возвращают частное своих аргументов. Числовые аргументы сначала преобразуются к общему типу. Деление целых чисел возвращает вещественное число, в то время как деление с отбрасыванием дробной части целых чисел приводит к целому числу; результатом является математическое деление с применением функции «округления вниз» к результату. Деление на ноль вызывает исключение ZeroDivisionError.
Эту операцию можно настроить, используя специальные методы __truediv__() и __floordiv__().
Оператор % (остаток от деления) возвращает остаток от деления первого аргумента на второй. Числовые аргументы сначала преобразуются к общему типу. Нулевой правый аргумент вызывает исключение ZeroDivisionError. Аргументы могут быть числами с плавающей точкой, например, 3.14%0.7 равно 0.34 (поскольку 3.14 равно 4*0.7 + 0.34.) Оператор остатка от деления всегда возвращает результат со знаком, совпадающим со знаком своего второго операнда (или ноль); абсолютное значение результата строго меньше абсолютного значения второго операнда 1.
Операторы деления с отбрасыванием дробной части и остатка от деления связаны следующим тождеством: x == (x//y)*y + (x%y). Операторы деления с отбрасыванием дробной части и остатка от деления также связаны со встроенной функцией divmod(): divmod(x, y) == (x//y,
x%y). 2.
Помимо выполнения операции остатка от деления над числами, оператор % также перегружается объектами строк для выполнения форматирования строк старого стиля (также известного как интерполяция). Синтаксис форматирования строк описан в Справочнике по библиотеке Python, раздел Форматирование строк в стиле printf.
Операция остатка от деления может быть настроена с помощью специального метода __mod__().
Оператор деления с отбрасыванием дробной части, оператор остатка от деления и функция divmod() не определены для комплексных чисел. Вместо этого выполните преобразование в число с плавающей точкой с помощью функции abs(), если это уместно.
Оператор + (сложение) возвращает сумму своих аргументов. Аргументы должны быть либо оба числами, либо оба последовательностями одного типа. В первом случае числа преобразуются к общему типу, а затем складываются. Во втором случае последовательности конкатенируются.
Эту операцию можно настроить, используя специальные методы __add__() и __radd__().
Оператор - (вычитание) возвращает разность своих аргументов. Числовые аргументы сначала преобразуются к общему типу.
Эту операцию можно настроить, используя специальный метод __sub__().
6.8. Операции сдвига
Операции сдвига имеют более низкий приоритет, чем арифметические операции:
shift_expr ::= a_expr | shift_expr ("<<" | ">>") a_expr
Эти операторы принимают целые числа в качестве аргументов. Они сдвигают первый аргумент влево или вправо на количество бит, заданное вторым аргументом.
Эту операцию можно настроить, используя специальные методы __lshift__() и __rshift__().
Сдвиг вправо на n бит определяется как деление с отбрасыванием дробной части на pow(2,n). Сдвиг влево на n бит определяется как умножение на pow(2,n).
6.9. Бинарные побитовые операции
Каждая из трех побитовых операций имеет разный уровень приоритета:
and_expr ::= shift_expr | and_expr "&" shift_expr xor_expr ::= and_expr | xor_expr "^" and_expr or_expr ::= xor_expr | or_expr "|" xor_expr
Оператор & возвращает побитовое И своих аргументов, которые должны быть целыми числами, или один из них должен быть пользовательским объектом, переопределяющим __and__() или __rand__() специальные методы.
Оператор ^ возвращает побитовое исключающее ИЛИ (XOR) своих аргументов, которые должны быть целыми числами, или один из них должен быть пользовательским объектом, переопределяющим __xor__() или __rxor__() специальные методы.
Оператор | возвращает побитовое ИЛИ (включительно) своих аргументов, которые должны быть целыми числами, или один из них должен быть пользовательским объектом, переопределяющим __or__() или __ror__() специальные методы.
6.10. Сравнения
В отличие от C, все операции сравнения в Python имеют одинаковый приоритет, который ниже, чем приоритет любой арифметической, сдвигающей или побитовой операции. Также в отличие от C, выражения, такие как a < b < c имеют интерпретацию, которая является стандартной в математике:
comparison ::= or_expr (comp_operator or_expr)*
comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="
| "is" ["not"] | ["not"] "in"
Сравнения возвращают булевы значения: True или False. Пользовательские методы богатых сравнений могут возвращать значения, отличные от булевых. В этом случае Python вызовет bool() над таким значением в контексте булевой проверки.
Сравнения можно объединять произвольно, например, x < y <= z эквивалентно x < y and y <= z, за исключением того, что y вычисляется только один раз (но в обоих случаях z не вычисляется вообще, когда x < y оказывается ложным).
Формально, если a, b, c, …, y, z — выражения, а op1, op2, …, opN — операторы сравнения, то a op1 b op2 c ... y opN z эквивалентно a op1 b and b op2 c and ... y opN z, за исключением того, что каждое выражение вычисляется не более одного раза.
Обратите внимание, что a op1 b op2 c не подразумевает никакого сравнения между a и c, поэтому, например, x < y > z вполне законно (хотя, возможно, и не очень красиво).
6.10.1. Сравнение значений
Операторы <, >, ==, >=, <=, и != сравнивают значения двух объектов. Объекты не обязаны иметь одинаковый тип.
В главе Объекты, значения и типы говорится, что объекты имеют значение (кроме типа и идентификатора). Значение объекта — довольно абстрактное понятие в Python: например, нет стандартного способа доступа к значению объекта. Кроме того, нет требования, чтобы значение объекта строилось каким-то определённым образом, например, состояло из всех его атрибутов данных. Операторы сравнения реализуют определённое понятие значения объекта. Можно представить их как определение значения объекта косвенно, путём реализации сравнения.
Поскольку все типы являются (прямыми или косвенными) подтипами object, они наследуют поведение по умолчанию для сравнения от object. Типы могут настраивать поведение сравнения, реализуя методы богатого сравнения, такие как __lt__(), описанные в Основные настройки.
Поведение по умолчанию для сравнения на равенство (== и !=). основано на идентичности объектов. Следовательно, сравнение на равенство экземпляров с одинаковой идентичностью приводит к равенству, а сравнение на равенство экземпляров с разными идентичностями — к неравенству. Мотивацией этого поведения по умолчанию является стремление к тому, чтобы все объекты были рефлексивными (т. е. x is y подразумевает x == y).
Поведение по умолчанию для сравнения по порядку (<, >, <=, и >=). не предоставляется; попытка вызывает TypeError. Мотивацией этого поведения по умолчанию является отсутствие аналогичного инварианта для равенства.
Поведение по умолчанию для сравнения на равенство, когда экземпляры с разными идентичностями всегда не равны, может противоречить тому, что требуют типы, имеющие осмысленное определение значения объекта и равенства на основе значения. Такие типы должны настраивать поведение сравнения, и на самом деле ряд встроенных типов это сделали.
В следующем списке описано поведение сравнения наиболее важных встроенных типов.
-
Числа встроенных числовых типов (Числовые типы — int, float, complex) и типов стандартной библиотеки
fractions.Fractionиdecimal.Decimalможно сравнивать внутри и между своими типами, с ограничением, что комплексные числа не поддерживают сравнение по порядку. В пределах участвующих типов они сравниваются математически (по алгоритму) правильно без потери точности.Значения не чисел
float('NaN')иdecimal.Decimal('NaN')являются специальными. Любое упорядоченное сравнение числа с значением не числа ложно. Противоинтуитивное следствие заключается в том, что значения не чисел не равны самим себе. Например, еслиx = float('NaN'),3 < x,x < 3иx == xвсе ложны, аx != x— истинно. Это поведение соответствует стандарту IEEE 754. -
NoneиNotImplemented— это синглтоны. PEP 8 рекомендует, чтобы сравнения для синглтонов всегда выполнялись с использованиемisилиis not, а не операторов равенства. - Двоичные последовательности (экземпляры
bytesилиbytearray) могут сравниваться внутри и между своими типами. Они сравниваются лексикографически с использованием числовых значений своих элементов. -
Строки (экземпляры
str) сравниваются лексикографически с использованием числовых значений кодовых точек Юникода (результат встроенной функцииord()) их символов. 3Строки и двоичные последовательности не могут быть непосредственно сравнены.
-
Последовательности (экземпляры
tuple,listилиrange) могут сравниваться только в рамках каждого из своих типов, при ограничении, что диапазоны не поддерживают сравнение по порядку. Сравнение на равенство между этими типами приводит к неравенству, а сравнение по порядку между этими типами вызываетTypeError.Последовательности сравниваются лексикографически с использованием сравнения соответствующих элементов. Встроенные контейнеры обычно предполагают, что идентичные объекты равны самим себе. Это позволяет им пропускать проверки на равенство для идентичных объектов, чтобы повысить производительность и сохранить свои внутренние инварианты.
Лексикографическое сравнение встроенных коллекций работает следующим образом:
- Для сравнения двух коллекций на равенство они должны иметь одинаковый тип, одинаковую длину и каждая пара соответствующих элементов должна сравниваться на равенство (например,
[1,2] == (1,2)ложно, потому что типы не совпадают). - Коллекции, которые поддерживают сравнение по порядку, упорядочиваются так же, как и их первые неравные элементы (например,
[1,2,x] <= [1,2,y]имеет то же значение, что иx <= y). Если соответствующего элемента не существует, короче коллекция упорядочивается первой (например,[1,2] < [1,2,3]истинно).
- Для сравнения двух коллекций на равенство они должны иметь одинаковый тип, одинаковую длину и каждая пара соответствующих элементов должна сравниваться на равенство (например,
-
Отображения (экземпляры
dict) сравниваются на равенство только в том случае, если они имеют равные пары(key, value). Сравнение на равенство ключей и значений обеспечивает рефлексивность.Сравнения по порядку (
<,>,<=, и>=). вызываютTypeError. -
Множества (экземпляры
setилиfrozenset) могут сравниваться внутри и между своими типами.Они определяют операторы сравнения по порядку, обозначающие подмножества и надмножества. Эти отношения не определяют полных порядков (например, два множества
{1,2}и{2,3}не равны, не являются подмножествами друг друга и не являются надмножествами друг друга). Соответственно, множества не являются подходящими аргументами для функций, которые зависят от полного порядка (например,min(),max()иsorted()дают неопределённые результаты, если в качестве входных данных передан список множеств).Сравнение множеств обеспечивает рефлексивность его элементов.
- Большинство других встроенных типов не имеют реализованных методов сравнения, поэтому они наследуют поведение сравнения по умолчанию.
Пользовательские классы, которые настраивают поведение сравнения, должны придерживаться некоторых правил согласованности, если это возможно:
-
Сравнение на равенство должно быть рефлексивным. Другими словами, идентичные объекты должны сравниваться на равенство:
x is yподразумеваетx == y -
Сравнение должно быть симметричным. Другими словами, следующие выражения должны давать один и тот же результат:
x == yиy == xx != yиy != xx < yиy > xx <= yиy >= x -
Сравнение должно быть транзитивным. Следующие (неполные) примеры иллюстрируют это:
x > y and y > zподразумеваетx > zx < y and y <= zподразумеваетx < z -
Обратное сравнение должно приводить к логическому отрицанию. Другими словами, следующие выражения должны давать один и тот же результат:
x == yиnot x != yx < yиnot x >= y(для полного порядка)x > yиnot x <= y(для полного порядка)Последние два выражения относятся к полностью упорядоченным коллекциям (например, к последовательностям, но не к множествам или отображениям). См. также декоратор
total_ordering(). - Результат
hash()должен быть согласован с равенством. Объекты, которые равны, должны либо иметь одинаковое значение хеша, либо быть помечены как нехешируемые.
Python не навязывает этих правил согласованности. На самом деле, значения не чисел являются примером того, как эти правила не соблюдаются.
6.10.2. Операции проверки принадлежности
Операторы in и not in проверяют принадлежность. x in
s принимает значение True, если x является элементом s, и False в противном случае. x not in s возвращает отрицание x in s. Все встроенные последовательности и типы множеств, а также словари поддерживают это, для словарей in проверяет, содержит ли словарь заданный ключ. Для контейнерных типов, таких как список, кортеж, множество, неизменяемое множество, словарь или collections.deque, выражение x in y эквивалентно any(x is e or x == e for e in y).
Для строк и типов байтов x in y равно True тогда и только тогда, когда x является подстрокой y. Эквивалентная проверка y.find(x) != -1. Пустые строки всегда считаются подстрокой любой другой строки, поэтому "" in "abc" вернёт True.
Для пользовательских классов, которые определяют метод __contains__(), x in
y возвращает True если y.__contains__(x) возвращает истинное значение, и False в противном случае.
Для пользовательских классов, которые не определяют __contains__(), но определяют __iter__(), x in y равно True если при итерации по y генерируется некоторое значение z, для которого выражение x is z or x == z истинно. Если во время итерации возникает исключение, это как если бы in вызвало это исключение.
Наконец, пробуется протокол старой итерации: если класс определяет __getitem__(), x in y равно True тогда и только тогда, когда существует неотрицательный целочисленный индекс i такой, что x is y[i] or x == y[i], и ни один более низкий целочисленный индекс не вызывает исключение IndexError. (Если возникает любое другое исключение, это как если бы in вызвало это исключение).
Оператор not in определен как имеющий обратное логическое значение in.
6.10.3. Сравнения по идентичности
Операторы is и is not проверяют идентичность объекта: x
is y истинно тогда и только тогда, когда x и y — один и тот же объект. Идентичность объекта определяется с помощью функции id(). x is not y возвращает обратное логическое значение. 4
6.11. Логические операции
or_test ::= and_test | or_test "or" and_test and_test ::= not_test | and_test "and" not_test not_test ::= comparison | "not" not_test
В контексте логических операций, а также когда выражения используются в операторах управления потоком, следующие значения интерпретируются как ложные: False, None, нулевые числовые значения всех типов, и пустые строки и контейнеры (включая строки, кортежи, списки, словари, множества и неизменяемые множества). Все остальные значения интерпретируются как истинные. Пользовательские объекты могут настроить своё истинностное значение, предоставив метод __bool__().
Оператор not возвращает True если его аргумент ложный, False в противном случае.
Выражение x and y сначала вычисляет x; если x ложно, возвращается его значение; в противном случае вычисляется y и возвращается полученное значение.
Выражение x or y сначала вычисляет x; если x истинно, возвращается его значение; в противном случае вычисляется y и возвращается полученное значение.
Обратите внимание, что ни and, ни or не ограничивают возвращаемое значение и тип значениями False и True, а возвращают последний вычисленный аргумент. Это иногда бывает полезно, например, если s — это строка, которая должна быть заменена значением по умолчанию, если она пустая, то выражение s or 'foo' возвращает желаемое значение. Поскольку not должен создать новое значение, он возвращает булево значение независимо от типа своего аргумента (например, not 'foo' производит False вместо ''.)
6.12. Выражения присваивания
assignment_expression ::= [identifier ":="] expression
Выражение присваивания (иногда также называемое «именованное выражение» или «выражение walrus») присваивает expression identifier, одновременно возвращая значение expression.
Один из распространённых случаев использования — обработка сопоставленных регулярных выражений:
if matching := pattern.search(data):
do_something(matching)
Или, при обработке потока файла по частям:
while chunk := file.read(9000):
process(chunk)
Выражения присваивания должны быть заключены в скобки, когда используются как операторы выражений и как подвыражения в операциях срезов, условных выражениях, лямбда-выражениях, выражениях с именованными аргументами и выражениях со списками, если и в assert, with, и assignment операторах. Во всех остальных местах, где они могут использоваться, скобки не требуются, включая if и while операторы.
Новое в версии 3.8: См. PEP 572 для получения более подробной информации об выражениях присваивания.
6.13. Условные выражения
conditional_expression ::= or_test ["if" or_test "else" expression] expression ::= conditional_expression | lambda_expr
Условные выражения (иногда называемые «тройным оператором») имеют самый низкий приоритет среди всех операций Python.
Выражение x if C else y сначала вычисляет условие C, а не x. Если C истинно, вычисляется x, и возвращается его значение; в противном случае вычисляется y и возвращается его значение.
См. PEP 308 для получения более подробной информации об условных выражениях.
6.14. Лямбда-выражения
lambda_expr ::= "lambda" [parameter_list] ":" expression
Лямбда-выражения (иногда называемые лямбда-формами) используются для создания анонимных функций. Выражение lambda parameters: expression возвращает объект функции. Этот неописанный объект ведёт себя как объект функции, определённый как:
def <lambda>(parameters):
return expression
См. раздел Определения функций для синтаксиса списков параметров. Обратите внимание, что функции, созданные с помощью лямбда-выражений, не могут содержать операторы или аннотации.
6.15. Списки выражений
expression_list ::= expression ("," expression)* [","]
starred_list ::= starred_item ("," starred_item)* [","]
starred_expression ::= expression | (starred_item ",")* [starred_item]
starred_item ::= assignment_expression | "*" or_expr
За исключением случаев, когда они являются частью отображения списка или множества, список выражений, содержащий по крайней мере одну запятую, генерирует кортеж. Длина кортежа равна количеству выражений в списке. Выражения вычисляются слева направо.
Звёздочка * обозначает распаковку итерируемых объектов. Его операнд должен быть итерируемым объектом. Итерируемый объект раскладывается на последовательность элементов, которые включаются в новый кортеж, список или множество в месте распаковки.
Новое в версии 3.5: Распаковка итерируемых объектов в списках выражений, изначально предложенная в PEP 448.
Запятая в конце нужна только для создания единственного кортежа (также известного как сингултон); она необязательна во всех остальных случаях. Единственное выражение без запятой в конце не создаёт кортеж, а возвращает значение этого выражения. (Чтобы создать пустой кортеж, используйте пустую пару скобок: ().)
6.16. Порядок вычисления
Python вычисляет выражения слева направо. Обратите внимание, что при вычислении присваивания правая часть вычисляется до левой.
В следующих строках выражения будут вычислены в арифметическом порядке их индексов:
expr1, expr2, expr3, expr4
(expr1, expr2, expr3, expr4)
{expr1: expr2, expr3: expr4}
expr1 + expr2 * (expr3 - expr4)
expr1(expr2, expr3, *expr4, **expr5)
expr3, expr4 = expr1, expr2
6.17. Приоритет операторов
В следующей таблице суммируется приоритет операторов в Python, от самого высокого (наиболее сильного) до самого низкого (наименее сильного). Операторы в одной ячейке имеют одинаковый приоритет. Если синтаксис не указан явно, операторы являются бинарными. Операторы в одной ячейке группируются слева направо (за исключением возведения в степень и условных выражений, которые группируются справа налево).
Обратите внимание, что сравнения, проверки принадлежности и проверки тождественности имеют одинаковый приоритет и обладают функцией цепочечного сравнения, как описано в разделе Сравнения.
Оператор | Описание |
|---|---|
|
| Связывание или выражение в скобках, список, словарь, множество |
| Индексирование, срезы, вызов, ссылка на атрибут |
Выражение 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) и абстрактные символы (например, «ЛАТИНСКАЯ ПРОПИСНАЯ БУКВА А»). Хотя большинство абстрактных символов в Unicode представлены только одной кодовой точкой, существует ряд абстрактных символов, которые дополнительно могут быть представлены последовательностью более чем одной кодовой точки. Например, абстрактный символ «ЛАТИНСКАЯ ПРОПИСНАЯ БУКВА С С ЦЕДЬЮ» может быть представлен одним прекомпонованным символом в кодовой позиции U+00C7 или как последовательность основного символа в кодовой позиции U+0043 (ЛАТИНСКАЯ ПРОПИСНАЯ БУКВА С), за которой следует комбинирующий символ в кодовой позиции U+0327 (КОМБИНИРУЮЩАЯ ЦЕДЬЯ).
Операторы сравнения для строк сравнивают на уровне кодовых точек Unicode. Это может быть нелогично для человека. Например,
"\u00C7" == "\u0043\u0327"являетсяFalse, даже несмотря на то, что обе строки представляют один и тот же абстрактный символ «ЛАТИНСКАЯ ПРОПИСНАЯ БУКВА С С ЦЕДЬЮ».Для сравнения строк на уровне абстрактных символов (то есть интуитивно для человека) используйте
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.11/reference/expressions.html