Готовый перевод The Python Language Reference / Справочник по языку Python: 5. Expressions

Внимание! Этот перевод, возможно, ещё не готов, так как модераторы установили для него статус «идёт перевод»

5. Выражения

Этот раздел разъясняет значение элементов выражений на Питоне.

Замечание о синтаксисе:
В этом и следующем разделах расширенная нотация BNF будет использоваться для описания синтаксиса, а не для лексического анализа. Когда (как одна из альтернатив) синтактическое правило имеет форму

name ::= othername

и не даётся дальнейшей расшифровки, то такая формулировка подразумевает, что "name" значит то же, что и "othername" .

-

5.1. Арифметические преобразования

Когда далее в описании арифметического оператора используется фраза "числовые аргументы преобразуются к общему типу" - это значит, что реализация операторов для встроенных типов работает следующим образом:

Если любой из аргументов является комплексным числом, то другое преобразуется к комплексному;

иначе, если любой из аргументов является дробным числом, то другое преобразуется к дробному;

если же оба целые, то никакого преобразования не требуется.

К некоторым операторам применяются дополнительные правила (...) . Расширения должны определять свю собственную логику преобразований.

5.2. Атомы

Атомы являются самыми базовыми элементами выражений. Простейшими атомами являются идентификаторы и непосредственная запись данных ("литералы") . Формации заключённые в круглые, квадратные или фигурные скобки - тоже синтаксически относятся к атомам. Синтаксис атомов :

<code>atom      ::= identifier | literal | enclosure
enclosure ::= parenth_form | list_display | dict_display | set_display
              | generator_expression | yield_atom</code>

5.2.1. Идентификаторы (имена)

Идентификатор в роли атома является именем. Смотрите лексическое определение в разделе "Идентификаторы и ключевые слова" , а также документацию по именованию и связыванию в разделе "Именование и связывание" .

Когда данное имя назначено обьекту - интерпретация этого атома даёт этот обьект. Когда имя не назначено чему-либо - попытка интерпретировать его вызывает исключение "NameError" .

Модифицирование частных (локальных) имён : Когда идентификатор, встретившийся в тексте определения класса, начинается с двух или более символов подчёркивания и не оканчивается двумя или более символами подчёркивания – он считается частным именем данного класса. Частные имена заменяются на их длинную форму при генерации соответствующего кода. Эти длинные формы образуются добавлением в начале имени класса, у которого удаляются все подчёркивания в начале и ставится одно подчёркивание. Например : идентификатор «__spam» в классе «Ham» будет преобразован в «_Ham__spam» . Это преобразование не зависит от синтаксического контекста, в котором идентификатор был использован. Следует помнить, что в некоторых реализациях Питона может происходить обрезание имён, больших определённой длинны. Имена, состоящие только из подчёркиваний – не модифицируются.

5.2.2. Константы ("литералы")

Питон поддерживает явную запись значений (константы) для текстов, байтов и различных типов чисел :

<code>literal ::= stringliteral | bytesliteral
            | integer | floatnumber | imagnumber</code>

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

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

5.2.3. Формы в скобках

Формы в скобках – это необязательный список выражений, заключённый в скобки :

<code>parenth_form ::= "(" [expression_list] ")"</code>

Список выражений, заключённый в скобки даёт в результате список значений этих выражений – но: если этот список содержит хотябы одну запятую, то образуется кортеж; иначе результатом будет значение единственного выражения списка.

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

Заметьте, что кортежи образуются не скобками, а использованием оператора запятая. Исключением является пустой кортеж, для которого пустые скобки обязательны (без которых могли бы возникать неоднозначности, и опечатки могли бы оставаться незамеченными) .

5.2.4. Отображения для списков, наборов и словарей

Для создания списков, наборов и словарей Питон предоставляет специальный синтаксис, называемый отображения “displays” , для каждого в двух вариантах :

либо их содержимое перечисляется явно, либо

они вычисляются с помощью набора циклических и фильтрующих инструкций, что называется «сборка (списка)» («генерация (списка)» , «компоновка (списка)» , «(list) comprehension») .

Общий синтаксис сборок :

<code>comprehension ::= expression comp_for
comp_for      ::= "for" target_list "in" or_test [comp_iter]
comp_iter     ::= comp_for | comp_if
comp_if       ::= "if" expression_nocond [comp_iter]</code>

«Компоновка» состоит из одного выражения, после которого идёт минимум одно ключевое слово «for» после которого могут быть в любом количестве ключевые слова «for» или «if» . В случае, если таковые присутствуют, содержимое группы очередного из них – это то, что получается, если считать каждую группу «for» или «if» блоком, вложенным по отношению к тому, что левее, и интерпретировать это выражение, получая очередной элемент каждый раз, дойдя до самого внутреннего блока.

Заметьте, что «компоновки» исполняются в отдельной области, поэтому имена, которым были назначения в списке приёмников, не «просачиваются» во внешнюю область.

5.2.5. Отображение (запись, формулировка) списков

Отображение списка – это последовательность выражений (может быть пустая), заключённая в квадратные скобки :

<code>list_display ::= "[" [expression_list | comprehension] "]"</code>

Запись списка даёт в результате объект-список, содержание которого определено или перечислением выражений, или конструкцией генерации (компонования) списка (“comprehension”) . В первом варианте, когда дан список выражений, разделённых запятой – его элементы интерпретируются слева направо – и помещаются в объект-список в том же порядке. Во втором варианте, когда дана конструкция компоновки списка – список составляется из элементов, генерируемых этой конструкцией.

5.2.6. Отображение (запись, формулировка) множеств

Запись множества обозначается фигурными скобками, и признаком, отличающим его от словаря, является отсутствие двоеточий – разделителей ключей и значений :

<code>set_display ::= "{" (expression_list | comprehension) "}"</code>

Запись множества даёт в результате изменяемый объект-множество, содержание которого определено или перечислением выражений, или конструкцией генерации (компонования) списков (“comprehension”) . В первом варианте, когда дан список выражений, разделённых запятой – его элементы интерпретируются слева направо – и добавляются к объекту-множеству. Во втором варианте, когда дана конструкция компоновки списков – множество составляется из элементов, генерируемых этой конструкцией.

Пустое множество не может быть создано с помощью обозначения «<code>{}</code>» – эта запись создаёт пустой словарь.

5.2.7. Запись (обозначение, формулировка) словарей

Запись словаря – это последовательность (может быть пустая) пар ключ – данные, заключённая в фигурные скобки :

<code>dict_display       ::= "{" [key_datum_list | dict_comprehension] "}"
key_datum_list     ::= key_datum ("," key_datum)* [","]
key_datum          ::= expression ":" expression
dict_comprehension ::= expression ":" expression comp_for</code>

Запись словаря даёт в результате новый объект-словарь.

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

В конструкции сборки (генерации) словаря, в отличие от таковых для списков и множеств, должно присутствовать два выражения, разделённых двоеточием, за которыми следуют обычные конструкции «<code>for</code>» и «<code>if</code>» . При исполнении сборки каждая пара значений в качестве соответственно ключа и его значения вставляется в словарь в порядке генерации.

Ограничения того, каким типам могут принадлежать ключи (а не сопоставленные им объекты) – перечислены выше, в разделе “3.2. Иерархия стандартных типов” . (Коротко : ключ должен быть хешируемого типа, что сразу исключает любые изменяемые типы. ) Коллизии между одинаковыми ключами не детектируются – просто последнее значение (самое правое, по тексту) , сохранённое под данным ключом, заменяет предыдущие значения.

5.2.8. Генераторные выражения

Генераторное выражение – это компактная форма записи генераторов в скобках :

<code>generator_expression ::= "(" expression comp_for ")"</code>

Генераторное выражение даёт в результате новый объект-генератор. Синтаксис у этого выражения такой же, как и у генератора списка, за исключением того, что оно заключено в круглые скобки вместо квадратных или фигурных.

Переменные, используемые в генераторных выражениях, вычисляются отложенно, во время вызова метода «<code>__next__()</code>» у объекта-генератора (так же, как и для обычных генераторов) . Однако, самое левое выражение «<code>for</code>» вычисляется сразу же – поэтому ошибка в нём проявится раньше, чем в других частях кода, контролируемых данным генераторным выражением. Следующие (в том же генераторном выражении) «<code>for</code>» – не могут интерпретироваться сразу же, поскольку они могут зависеть от «<code>for</code>» слева. (Например : «<code>(x*y for x in range(10) for y in bar(x))</code>» . )

Скобки можно пропустить при вызове функции, у которой один аргумент. (Смотрите раздел <a href="http://docs.python.org/py3k/reference/expressions.html#calls">5.3.4. Calls</a> )

5.2.9. Выражения с «<code>yield</code>»

<code>yield_atom       ::= "(" yield_expression ")"
yield_expression ::= "yield" [expression_list]</code>

Ключевое слово «<code>yield</code>» используется только для задания генераторной функции и может использоваться только внутри определения функции. Чтобы превратить определение обычной функции в определение генераторной – достаточно использовать в этом определении инструкцию «<code>yield</code>» .

Вызов генераторной функции в качестве результата возвращает объект-итератор, называемый также генератор. И уже́ этот генератор управляет исполнением генераторной функции. Собственно исполнение начинается, когда вызывается один из методов этого объекта-итератора, и продолжается оно до первой встреченной инструкции «<code>yield</code>» , где исполнение опять приостанавливается, и аргумент инструкции «<code>yield</code>» возвращается в качестве результата вызова соответствующего метода. Под приостановкой подразумевается, что всё локальное состояние сохраняется, включая текущие значения локальных переменных, указатель на инструкцию, с которой продолжать, и внутренний стек вычислений. А когда, в результате следующего вызова одного из методов этого итератора, исполнение возобновляется, то оно продолжается точно так же, как если бы вместо «<code>yield</code>» был вызов обычной внешней функции. Значение выражения «<code>yield</code>» зависит от метода, возобновившего исполнение.

Всё это делает генераторные функции похожими на со-процедуры (“coroutines”) : они выдают результат многократно, у них более одной точки входа и их исполнение может быть приостановлено. Единственное отличие в том, что генераторная функция не может управлять тем, что должно исполняться, после того, как она приостанавливается – контроль всегда возвращается туда, откуда этот генератор был вызван.

Инструкция «<code>yield</code>» допустима в ветви «<code>try</code>» конструкции «<code>try ... finally</code>» . Если данный генератор не был завершён до его “деструкции” (вследствие достижения ноля счётчиком ссылок или действием “сборщика мусора”) , то будет вызван метод «<code>close()</code>» данного генератора, что позволяет исполниться незавершённым ветвям «<code>finally</code>» .

Генераторная функция для управления её исполнением имеет следующие методы :

<code>generator.__next__()</code>

Начинает исполнение генераторной функции или продолжает его с последней исполненной инструкции «<code>yield</code>» . Если в результате вызова метода «<code>__next__()</code>» генераторная функция продолжает работу, которая была приостановлена вызовом функции «<code>yield</code>» , то эта «<code>yield</code>» завершается, выдавая результат «<code>None</code>» . Затем исполнение генератора продолжается до следующей инструкции «<code>yield</code>» , где оно опять приостанавливается, а значение выражения-аргумента инструкции «<code>yield</code>» возвращается в место вызова функции «<code>next()</code>» . Если происходит выход из генератора не по инструкции «<code>yield</code>» , то вызывается исключение «<code>StopIteration</code>» .

В норме этот метод не вызывается прямо, а, например, косвенно циклом или встроенной функцией «<code>next()</code>» .

<code>generator.send(value)</code>

Продолжает исполнение генераторной функции с последней исполненной инструкции «<code>yield</code>» , которая завершается, выдавая в качестве результата аргумент функции «<code>send()</code>» . Затем исполнение генератора продолжается до следующей инструкции «<code>yield</code>» , где оно опять приостанавливается, а значение выражения-аргумента инструкции «<code>yield</code>» возвращается в место вызова функции «<code>send()</code>» . Если происходит выход из генератора не по инструкции «<code>yield</code>» , то вызывается исключение «<code>StopIteration</code>» (и возврат в «<code>send()</code>» не происходит) . Если функция «<code>send()</code>» вызывается для генератора, который ещё не был запущен и приостановлен посредством «<code>yield</code>» , то она должна вызывается только с аргументом «<code>None</code>» (потому, что нет функции «<code>yield</code>» , ожидающей значение) .

<code>generator.throw(type[, value[, traceback]])</code>

Приводит к исключению типа «<code>type</code>» в том месте генератора, где он был остановлен. Если генератор перехватывает это исключение, то : или функция «<code>generator.throw()</code>» возвращает следующее значение, выданное генератором, или, если генератор завершается без инструкции «<code>yielded</code>» , то вызывается исключение «<code>StopIteration</code>» . Если же генератор не перехватывает переданное ему исключение, или генерирует какое-либо исключение сам, то происходит возврат к функции «<code>generator.throw()</code>» с этим исключением.

<code>generator.close()</code>

Вызывает «<code>GeneratorExit</code>» в месте, где генератор был приостановлен. Если генератор после этого вызывает «<code>StopIteration</code>» (путём нормального выхода, или если уже был остановлен) или «<code>GeneratorExit</code>» (путём неперехватывания этого исключения) , то происходит выход из «<code>generator.close()</code>» с результатом «<code>None</code>» . Если генератор вызывает любое другое исключение, то оно возвращается в «<code>generator.close()</code>» . Если же генератор выдаёт значение, то вызывается «<code>RuntimeError</code>» .

Простой пример, демонстрирующий поведение объектов-генераторов и генераторных функций :

<code>>>> 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.</code>

-

Смотрите также :

<a href="http://www.python.org/dev/peps/pep-0255">PEP 0255</a> - Simple Generators (простые генераторы)

Предложение по добавлению в Питон генераторов и инструкции "yield" .

<a href="http://www.python.org/dev/peps/pep-0342">PEP 0342</a> - Coroutines via Enhanced Generators (Параллельное программирование с помощью "улучшенных генераторов")

Предложение по улучшению API и синтаксиса генераторов, делающему их пригодными для простейшего параллельного программирования.

5.3. Первичные выражения

Первичные выражения – это базовые понятия, операции языка, такие как : взятие атрибута, взятие элемента(элементов) по индексу, вызов функции. У них следующий синтаксис :

<code>primary ::= atom | attributeref | subscription | slicing | call</code>

5.3.1. Обращение к атрибутам

Обращение к атрибуту состоит из другого первичного выражения (в том числе атома) после которого идёт точка и пото́м имя (атрибута) .

<code>attributeref ::= primary "." identifier</code>

Значением выражения «<code>primary</code>» должен быть объект, тип которого поддерживает обращение к атрибутам (таких типов – большинство) . К этим объектам делается запрос выдать атрибут с указанным именем («<code>identifier</code>») . Этот процесс может быть настроен переопределением метода «<code>__getattr__()</code>» . Тип и значение возвращаемого атрибута задаётся объектом, которому тот принадлежит, причём каждое обращение к атрибуту может выдавать уже́ новый объект. Если этот атрибут недоступен, то вызывается исключение «<code>AttributeError</code>» .

5.3.2. Обращение к элементу по индексу

Взятие по индексу выделяет определённый элемент из последовательности (например, из строки, кортежа, списка) или из словаря :

<code>subscription ::= primary "[" expression_list "]"</code>

Значением выражения «<code>primary</code>» должен быть объект, тип которого поддерживает взятие элемента по индексу. Определённые пользователем объекты тоже могут поддерживать взятие элемента – определив метод «<code>__getitem__()</code>» .

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

Если «<code>primary</code>» является отображением (словарём) , то значением «<code>expression_list</code>» должен быть объект, являющийся одним из ключей данного отображения, и тогда извлекается значение, соответствующее данному ключу. «<code>expression_list</code>» является кортежем, если только в списке не ровно одно выражение.

Если «<code>primary</code>» является последовательностью, то значением «<code>expression_list</code>» должно быть целое число. Если это число негативное, то к нему прибавляется длина последовательности (таким образом, «<code>x[-1]</code>» указывает на последний элемент в «<code>x</code>» ) . Результирующее значение должно быть неотрицательным целым меньшим длины данной последовательности. И в качестве результата извлекается элемент, чьим индексом является это значение (учитывая, что элементы номеруются с ноля) .

Элементами текстовых данных (“строк”) являются символы. Причём символ является не отдельным типом данных, а такою же строкой, но только из одного символа.

5.3.3. “Срезы”

Срез выделяет диапазон элементов в объекте-последовательности (например в строке, в кортеже) . Срезы могут использоваться и как выражения (дающие в результате значение) и как цель для назначения или инструкции «<code>del</code>» . Синтаксис следующий :

<code>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</code>

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

Смысл среза следующий. Значением выражения «<code>primary</code>» должен быть объект-отображение, у которого берётся элемент по индексу (с помощью обычного метода «<code>__getitem__()</code>» ) со значением индекса, вычисляемым из «<code>slice_list</code>» – как показано далее. Если «<code>slice_list</code>» содержит хотя-бы одну запятую, то ключом является кортеж срезов, иначе ключом является один срез. .........

5.3.4. Вызовы

При вызове вызывается (исполняется) вызываемый (исполнимый) объект (например функция) , которому передаётся список параметров (может быть пустым) :

<code>call                 ::= primary "(" [argument_list [","] | comprehension] ")"
argument_list        ::= positional_arguments ["," keyword_arguments]
                           ["," "*" expression] ["," keyword_arguments]
                           ["," "**" expression]
                         | keyword_arguments ["," "*" expression]
                           ["," keyword_arguments] ["," "**" expression]
                         | "*" expression ["," keyword_arguments] ["," "**" expression]
                         | "**" expression
positional_arguments ::= expression ("," expression)*
keyword_arguments    ::= keyword_item ("," keyword_item)*
keyword_item         ::= identifier "=" expression</code>

После позиционных и именованных аргументов может стоять конечная (лишняя) запятая – она не имеет никакого значения и на смысл не влияет.

Значением «<code>primary</code>» должен быть вызываемый объект (определяемая пользователем или встроенная функция, метод встроенного объекта, объект-класс, метод экземпляра класса или любой объект с методом «<code>__call__()</code>» ) . Все выражения-аргументы вычисляются прежде, чем делается попытка вызова. Синтаксис списка “формальных” параметров в определении функции смотрите в разделе «Функции» .

Если даны именованные аргументы, то они сначала преобразуются в позиционные следующим образом. Сначала для “формальных” параметров создаётся список незаполненных мест. Если дано N позиционных аргументов, то они помещаются в N первых из этих мест. Далее для каждого именованного аргумента определяется, каким по счёту он идёт в формальных параметрах определения функции – и в такое же по счёту место помещается его значение (даже если это значение «<code>None</code>» ) . Если это место оказывается уже́ занятым, то вызывается исключение «<code>TypeError</code>» . Когда все аргументы обработаны – места, оставшиеся необработанными заполняются соответствующими значениями по-умолчанию из определения функции. (Значения по-умолчанию вычисляются один раз – когда выполняется определение функции – таким образом, изменяемый объект, например список или словарь, использованный как значение по-умолчанию, будет сохраняться между вызовами функции, и его предыдущее значение будет доступно, если в него не будет передано значение в соответствующем аргументе при вызове. ) Если останутся незаполненными места, для которых нет значений по-умолчанию, то вызывается исключение «<code>TypeError</code>» . Заполненный таким образом список используется как список аргументов функции.

Особенности реализации “CPython” : В какой-либо реализации могут быть встроенные функции, чьи позиционные параметры не имеют имён (несмотря на то, что в ихней документации для удобства используются некие “имена” ) и, таким образом, эти параметры не могут быть переданы как именованные аргументы. Как пример – функции, реализованные на “C” с использованием «<code>PyArg_ParseTuple()</code>» для разбора аргументов .

Если дано больше аргументов, чем параметров в определении, то вызывается исключение «<code>TypeError</code>» , если только в определении не присутствует параметр с синтаксисом с «<code>*</code>» – в этом случае этот параметр получает кортеж, содержащий лишние аргументы (или пустой кортеж, если нет таковых) .

Если какой-либо именованный аргумент не соответствует имени параметра в определении, то вызывается исключение «<code>TypeError</code>» , если только в определении не присутствует параметр с синтаксисом с «<code>**</code>» – в этом случае этот параметр получает словарь (или пустой словарь, если нет лишних), содержащий лишние именованные аргументы, чьи имена становятся ключами – и они получают соответствующие значения.

Если в вызове функции встречается синтаксис «<code>*expression</code>» , то значением «<code>expression</code>» должна быть последовательность. Элементы из этой последовательности извлекаются и воспринимаются как дополнительные позиционные аргументы – тоесть, если в вызове даны позиционные аргументы x1,..., xN и «<code>expression</code>» даёт элементы y1, ..., yM , то это эквивалентно вызову с M+N штуками аргументов x1, ..., xN, y1, ..., yM .

Следствием из этого является то, что, хотя «<code>*expression</code>» может идти после некоторых именованных аргументов, «<code>*expression</code>» обрабатывается раньше них (и раньше аргумента «<code>**expression</code>» ) . Таким образом :

<code>>>> def f(a, b):
... print(a, b)
...
>>> f(b=1, *(2,))
2 1
>>> f(a=1, *(2,))
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in ?
TypeError: f() got multiple values for keyword argument 'a'
>>> f(1, *(2,))
1 2</code>

-

-

Использование в вызове одновременно именованных аргументов и синтаксиса «<code>*expression</code>» является редким – только поэтому на практике редко возникают и соответствующие недоразумения.

Если в вызове функции встречается синтаксис «<code>**expression</code>» , то значением «<code>expression</code>» должно быть отображение (словарь) . Элементы из этого отображения извлекаются и воспринимаются как дополнительные именованные аргументы. Если некий ключ (имя) присутствует и в «<code>expression</code>» и как явный именованный аргумент, то вызывается исключение «<code>TypeError</code>» .

Параметры в определении, использующие синтаксис «<code>*identifier</code>» или «<code>**identifier</code>» , не могут быть использованы как позиционные получатели (места́) или как имена именованных аргументов.

Вызов всегда возвращает какое-либо значение (в частности «<code>None</code>» ) – если только этот вызов не привёл к исключению. То, каким способом это значение вычисляется – зависит от типа вызываемого объекта.

-

Если это написанная пользователем функция :

Функции передаётся список аргументов, и её блок кода исполняется. Первое, что происходит в блоке кода – это связывание имён “формальных” параметров с предоставленными аргументами (подробнее в разделе «Определение функций» ) . Если в блоке кода исполняется инструкция «<code>return</code>» , то она задаёт возвращаемое функцией значение – иначе, по-умолчанию, – возвращается «<code>None</code>» .

Если это встроенные функция или метод :

Результат зависит от интерпретатора. Смотрите “Встроенные функции” .

Если это объект-класс :

Возвращается новый экземпляр этого класса.

Если это метод экземпляра класса :

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

Если это экземпляр класса :

В классе должен быть определён метод «<code>__call__()</code>» (одноимённый метод определённый в самом экземпляре – игнорируется при простом вызове экземпляра ) , в остальном – аналогично вызову метода экземпляра класса.

5.4. Оператор возведения в степень

Оператор степени имеет бо́льший приоритет, чем однооперандные операторы непосредственно слева, но меньший, чем однооперандные операторы непосредственно справа. Его синтаксис :

<code>power ::= primary ["**" u_expr]</code>

Таким образом в последовательности без кавычек из степени и однооперандных операторов вычисление выполняется с права налево (это не влияет на порядок действий вутри выражений операндов) : «<code>-1**2</code>» даёт результат «<code>-1</code>» .

Оператор степени имеет тот же смысл, что и встроенная функция «<code>pow()</code>» – если вызывается с двумя аргументами : левый аргумент возводится в степень правого. Числовые аргументы сначала преобразуются к общему типу, и результат будет этого же типа.

Для целочисленных операндов результат тоже будет целым, если только второй операнд не негативный – в таком случае все аргументы преобразуются в дробные, и результат тоже будет дробный. Например : «<code>10**2</code>» даёт «<code>100</code>» , но «<code>10**-2</code>» даёт «<code>0.01</code>» .

Возведение «<code>0.0</code>» в негативную степень вызывает исключение «<code>ZeroDivisionError</code>» . Возведение негативного числа в дробную степень даёт комплексное число (в прошлых версиях вызывалось исключение «<code>ValueError</code>» ) .

5.5. Однооперандные арифметические и побитовые операци

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

<code>u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr</code>

«-» (минус) негативирует (умножает на «-1» ) свой числовой аргумент.

«+» (плюс) не изменяет свой числовой аргумент.

Оператор «~» побитово инвертирует свой целочисленный аргумент, и для аргумента «x» определяется как «-(x+1)» .

Во всех трёх случаях – если аргумент не требуемого типа, то вызывается исключение «<code>TypeError</code>» .

5.6. Двухоперандные арифметические операции

У двухоперандных арифметических операций уровни приоритета соответствуют общепринятым. Заметьте, что некоторые из них также применяются для нечисловых типов. Кроме операции степени – среди них есть только два уровня приоритета : выше – для произведения и деления (одинаковый) , и ниже – для суммы и вычитания (одинаковый) .

<code>m_expr ::= u_expr | m_expr "*" u_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</code>

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

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

Оператор % (остаток деления) даёт остаток деления первого операнда на второй. Операнды должны быть оба чи́сла и они преобразуются к общему типу. При нолевом втором аргументе вызывается исключение «<code>ZeroDivisionError</code>» . Аргументы могут быть дробными числами, например, 3,14%0,7 равно 0,34 (поскольку 3,14 равно 4*0,7 + 0,34 ) . Результат всегда имеет знак, равный знаку делителя или же равен нолю. Модуль результата строго меньше модуля делителя. [1]

Операторы деления нацело и остатка связаны следующим равенством : «<code>x == (x//y)*y + (x%y)</code>» . Также они связаны со встроенной функцией «<code>divmod()</code>» : «<code>divmod(x, y) == (x//y, x%y)</code>» . [2]

В строковых объектах оператор «<code>%</code>» переопределён и используется для старого стиля форматирования текста (так называемые “interpolation” ) . Синтаксис такого форматирования определён в “Python Library Reference” раздел “<a>Old String Formatting Operations</a>” .

Операторы деления нацело, взятие остатка и функция «<code>divmod()</code>» не определены для комплексных чисел – требуется явное преобразование в дробные функцией «<code>abs()</code>» .

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

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

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

Операции сдвига имеют приоритет меньший, чем у арифметических операций :

<code>shift_expr ::= a_expr | shift_expr ( "&lt;&lt;" | ">>" ) a_expr</code>

Аргументы должны быть целыми числами. Затем производится сдвиг двоичного представления первого аргумента соответственно влево или вправо на количество бит равное второму аргументу.

Сдвиг влево определяется как умножение на 2 в степени второго аргумента («<code>a * pow(2, b)</code>») . Сдвиг вправо определяется как целая часть от деления на 2 в степени второго аргумента («<code>a // pow(2, b)</code>») .

5.8. Двоичные побитовые операции

Все эти три операции имеют разный приоритет :

<code>and_expr ::= shift_expr | and_expr "&" shift_expr
xor_expr ::= and_expr | xor_expr "^" and_expr
or_expr ::= xor_expr | or_expr "|" xor_expr</code>

Оператор «<code>&amp;</code>» производит побитовую операцию «И» («AND») над целочисленными аргументами.

Оператор «<code>^</code>» производит побитовую операцию «исключающее ИЛИ» («XOR») над целочисленными аргументами.

Оператор «<code>|</code>» производит побитовую операцию «ИЛИ» («OR») над целочисленными аргументами.

5.9. Сравнения

В отличие от «C» – все операции сравнения в Питоне имеют одинаковый приоритет, который ниже, чем у любых арифметических, сдвиговых или побитовых операций. Также, в отличие от «C» , выражения типа «<code>a &lt; b &lt; c</code>» интерпретируются, как это принято в математике.

<code>comparison    ::=  or_expr ( comp_operator or_expr )*
comp_operator ::=  "&lt;" | ">" | "==" | ">=" | "&lt;=" | "!="
                   | "is" ["not"] | ["not"] "in"</code>

Сравнения дают в результате булевы значения : «<code>True</code>» или «<code>False</code>» .

Сравнения могут соединяться в произвольные цепочки, например : «<code>x &lt; y &lt;= z</code>» эквивалентно «<code>x &lt; y and y &lt;= z</code>» , за исключением того, что «<code>y</code>» вычисляется только один раз (но в обоих вариантах «<code>z</code>» вообще не вычисляется, если «<code>x &lt; y</code>» не верно) .

Общее правило : если «<code>a, b, c, ..., y, z</code>» – выражения, и «<code>op1, op2, ..., opN</code>» – операторы сравнения, то «<code>a op1 b op2 c ... y opN z</code>» является эквивалентом «<code>a op1 b and b op2 c and ... y opN z</code>» , за исключением того, что каждое выражение вычисляется только один раз.

Заметьте, что «<code>a op1 b op2 c</code>» не подразумевает никаких сравнений «<code>a</code>» и «<code>c</code>» , так что, например, «<code>x &lt; y > z</code>» абсолютно приемлемо (хотя и не очень красиво) .

Операторы «<code>&lt;</code>» , «<code>&gt;</code>» , «<code>==</code>» , «<code>&gt;=</code>» , «<code>&lt;=</code>» и «<code>!=</code>» сравнивают значения двух объектов. Эти объекты не обязаны иметь одинаковый тип. Если оба являются числами, то они преобразуются к общему типу. Если не числа, то операторы «<code>==</code>» и «<code>!=</code>» всегда считают объекты отличающихся типов неравными, а операторы «<code>&lt;</code>» , «<code>&gt;</code>» , «<code>&gt;=</code>» и «<code>&lt;=</code>» вызывают «<code>TypeError</code>» для отличающихся типов, не имеющих реализации соответствующих операторов для данной пары типов. Вы можете контролировать поведение сравнения для объектов не встроенных типов, определяя методы расширенного сравнения типа «<code>__gt__()</code>» , как описано в разделе “Имена спецальных методов / Основные средства настройки классов” (“Basic customization”) .

Сравнение объектов одинакового типа зависит от типа :

Числа сравниваются арифметически.

Значения «<code>float('NaN')</code>» и «<code>Decimal('NaN')</code>» являются особыми. Они идентичны самим себе «<code>x is x</code>» , но не равны самим себе «<code>x != x</code>» . Более того, сравнение любого значения с “Not-a-Number” возвращает «<code>False</code>» . Например : и «<code>3 &lt; float('NaN')</code>» и «<code>float('NaN') &lt; 3</code>» вернут «<code>False</code>» .

“Байты” сравниваются поэлементно до первого несовпадения (лексикографически) , с использованием числовых значений их элементов.

“Строки” сравниваются посимвольно до первого несовпадения (лексикографически) , с использованием числовых эквивалентов (возвращаемых встроенной функцией «<code>ord()</code>» ) их элементов-симвлов.

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

Если последовательности не равны, то они упорядочиваются по первым несовпадающим элементам. Например, «<code>[1,2,x] &lt;= [1,2,y]</code>» имеет тот же результат, что и «<code>x &lt;= y</code>» . Если соответствующий элемент отсутствует, то более короткая последовательность меньше (идёт раньше) , например : «<code>[1,2]</code>» &lt; «<code>[1,2,3]</code>» .

Отображения (словари) равны только если равны их отсортированные по ключу списки пар ключ-значение (в данной реализации такое сравнение производится эффективно – без реального конструирования списков или сортирования). Другие результаты сравнения, кроме равенства – решаются соответственно, (?) но иначе не определены. Предыдущие версии Питона использовали сравнение таких отсортированных списков (из пар ключ-значение) по первому несовпадающему элементу (тоесть, “лексикографически” ) , но это было слишком затратно для наиболее распространенного случая – проверки только на равенство. Ещё более ранние версии Питона сравнивали словари только по факту того один и тот же ли это объект, но это приводило к неожиданностям – поскольку люди ожидали иметь возможность проверять пуст ли словарь, сравнивая его с «<code>{}</code>» (новым пустым словарём) .

Множества (sets) и фиксированные множества (frozensets) определяют операторы сравнения для реализации понятий подмножества и надмножества. Эти отношения не подразумевают определения полного упорядочивания (например, множества «<code>{1,2}</code>» и «<code>{2,3}</code>» ни равны, ни подмножество или надмножество одно для другого) . Соответственно – множества не являются годными аргументами для функций, результат которых зависит от полного упорядочивания. Например : «<code>min()</code>» , «<code>max()</code>» и «<code>sorted()</code>» выдают неопределённый результат, получив список множеств.

Большинство других объектов встроенных типов считаются неравными, за исключением случая, когда это оказывается один и тот же объект. Выбор того, считается ли один объект меньше другого, делается произвольно – но одинаково в течение всего исполнения программы.

Сравнение объектов различающихся типов зависит от того, предоставляет ли тип кого-либо из них явную поддержку для такого сравнения. Большинство числовых типов можно сравнивать друг с другом, но сравнение «<code>float</code>» с «<code>Decimal</code>» не поддерживается – для избежания неустранимой неясности, происходящей из особенностей представления (реализации) , например «<code>float('1.1')</code>» , чьё машинное представление является приближённым и, как следствие, является не строго равным «<code>Decimal('1.1')</code>» , чьё машинное представление строго соответствует записи. Когда межтиповое сравнение не поддерживается – возвращается «<code>NotImplemented</code>» . Это может создать иллюзию нетранзитивности между поддерживаемыми и неподдерживаемыми межтиповыми сравнениями. Например, «<code>Decimal(2) == 2</code>» и «<code>2 == float(2)</code>» , но «<code>Decimal(2) != float(2)</code>» .

Операторы «<code>in</code>» и «<code>not in</code>» проверяют на вхождение (членство) . «<code>x in s</code>» даёт результат «<code>True</code>» если «<code>x</code>» является членом «<code>s</code>» – в остальных случаях – результат «<code>False</code>» . Все встроенные последовательности и множества поддерживают эти инструкции, при этом для словаря подразумевается поиск во множестве его ключей. Для контейнерных типов – таких как список, кортеж, множество, фиксированное множество, словарь или «<code>collections.deque</code>» – выражение «<code>x in y</code>» является эквивалентом «<code>any(x is e or x == e for e in y)</code>» .

Для текстовых и байтовых типов «<code>x in y</code>» даёт результат «<code>True</code>» только если «<code>x</code>» является подстрокой для «<code>y</code>» . Эквивалентом является «<code>y.find(x) != -1</code>» . Пустой текст считается подстрокой для любого текста, тоесть : «<code>"" in "abc"</code>» вернёт «<code>True</code>» .

Для пользовательских классов, в которых определён метод «<code>__contains__()</code>» , результат операции «<code>in</code>» определяется исключительно этим методом.

Для пользовательских классов, в которых не определён метод «<code>__contains__()</code>» , но определён метод «<code>__iter__()</code>» , операция «<code>x in y</code>» даёт результат «<code>True</code>» , если при переборе элементов «<code>y</code>» находится хотя бы одно такое значение «<code>z</code>» , что «<code>x == z</code>» . Если при этом переборе происходит исключение, то эффект таков, как если бы оно произошло в самой операции «<code>in</code>» .

И, наконец, делается попытка использовать протокол перебора в старом стиле : если в классе определён «<code>__getitem__()</code>» , то «<code>x in y</code>» даёт в результате «<code>True</code>» только если есть такое неотрицательный целый индекс «<code>i</code>» , что «<code>x == y[i]</code>» и все меньшие индексы не вызывают исключение «<code>IndexError</code>» . Если происходит исключение любого другого типа, то эффект таков, как если бы оно произошло в самой операции «<code>in</code>» .

Оператор «<code>not in</code>» определён как отрицание логического результата «<code>in</code>» (над теми же операндами) .

Операторы «<code>is</code>» и «<code>is not</code>» проверяют на идентичность объекта : «<code>x is y</code>» даёт в результате «<code>True</code>» только если «<code>x</code>» и «<code>y</code>» являются одним и тем же объектом. «<code>is not</code>» даёт отрицание логического результата оператора «<code>is</code>» (над теми же операндами) .

5.10. Логические операции

Логические (булевы) операции имеют самый нижний приоритет из всех операций Питона :

<code>expression             ::= conditional_expression | lambda_form
expression_nocond      ::= or_test | lambda_form_nocond
conditional_expression ::= or_test ["if" or_test "else" expression]
or_test                ::= and_test | or_test "or" and_test
and_test               ::= not_test | and_test "and" not_test
not_test               ::= comparison | "not" not_test</code>

В контексте логических операций а также в выражениях-параметрах инструкций управления потоком программы (ветвления, циклы) – следующие значения интерпретируются как логическая ложь : «<code>False</code>» , «<code>None</code>» , число ноль любого типа, пустые строки, пустые контейнеры. Все остальные значения интерпретируются как логическая истина. Определённые пользователем объекты могут задать значение истинности определив метод «<code>__bool__()</code>» .

Оператор «<code>not</code>» даёт в результате «<code>True</code>» , если его аргумент является ложью, иначе – даёт в результате «<code>False</code>» .

-

Для выражения «<code>x and y</code>» сначала вычисляется значение выражения «<code>x</code>» – если это значение ложно, то возвращается это значение (которое было до приведения к логическому типу) , иначе дальше вычисляется и возвращается значение выражения «<code>y</code>» (без приведения к логическому типу) .

Для выражения «<code>x or y</code>» сначала вычисляется значение выражения «<code>x</code>» – если это значение истинно, то возвращается это значение (которое было до приведения к логическому типу) , иначе дальше вычисляется и возвращается значение выражения «<code>y</code>» (без приведения к логическому типу) .

Заметьте, что ни «<code>and</code>» , ни «<code>or</code>» не ограничивают значение и тип результата значениями «<code>False</code>» и «<code>True</code>» , а просто возвращают в неизменном виде значение операнда, взятого последним. Это иногда может быть полезно – например, если «<code>s</code>» – текст, который, если он пустой, должен быть заменён на текст по-умолчанию, то выражение «<code>s or 'foo'</code>» даёт какраз такой эффект. Поскольку операция «<code>not</code>» в любом случае должна сгенерировать новое значение, то она не заботится о том, чтобы вернуть значение того же типа, что и её аргумент, поэтому, например, «<code>not 'foo'</code>» выдаёт «<code>False</code>» , а не «<code>''</code>» .

5.11. Ламбда-функции

<code>lambda_form        ::= "lambda" [parameter_list]: expression
lambda_form_nocond ::= "lambda" [parameter_list]: expression_nocond</code>

Ламбда-выражения находятся в той же позиции, в которой ожидается обычное выражение. Они являются сокращённой формой создания анонимных функций. Выражение «<code>lambda arguments: expression</code>» возвращает вместо себя объект-функцию. Этот безымянный объект-функция ведёт себя, как если бы был определён так :

<code>def &lt;lambda&gt;(arguments):
    return expression</code>

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

5.12. Списки выражений

<code>expression_list ::= expression ( "," expression )* [","]</code>

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

Запятая в самом конце, после последнего элемента – требуется только для создания одноэлементного кортежа (“singleton” , “одиночка”) – в других случаях такая концевая запятая не требуется. Одиночное выражение без такой концевой запятой после него не создаёт кортеж, а просто возвращает само значение этого выражения. А для обозначения пустого кортежа используйте пустую пару круглых скобок : « <code>( )</code> » .

5.13. Очерёдность вычисления

Питон обрабатывает (вычисляет) выражения с лева направо. Заметьте, что при обработке назначений – сначала обрабатывается правая часть (источник) , потом левая (получатель) .

В следующем коде числа на концах имён выражений соответствуют очерёдности их обработки :

<code>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</code>

5.14. Обобщение

Следующая таблица показывает приоритетность операторов в Питоне – от наименьшей приоритетности (слабейшая связь с операндами) к наивысшей (сильнейшая связь) . Операторы в одной ячейке имеют одинаковую приоритетность. Если синтаксис не указан явно – подразумеваются двухоперандные операторы. Операторы из одной ячейки приоритетности, идущие в коде подряд, исполняются с лева направо (кроме операторов сравнения и возведения в степень, у которых обратный порядок исполнения) .

Оператор Описание
lambda ламбда-выражение
if – else выражение условия
or логическое ИЛИ
and логическое И
not x логическое НЕ
in, not in, is, is not, &lt;, &lt;=, &gt;, &gt;=, !=, == сравнения, проверки на идентичность или вхождение
| побитовое ИЛИ
^ побитовое исключающее ИЛИ (XOR)
&amp; побитовое И
&lt;&lt;, &gt;&gt; сдвиги
+, - сложение и вычитание
*, /, //, % умножение, деление, остаток [7]
+x, -x, ~x позитивация, негативация, побитовое НЕ
** степень [8]
x[index], x[index:index], x(arguments...), x.attribute индексация, вызов, обращение к атрибуту
(expressions...), [expressions...], {key:datum...}, {expressions...} записи: кортежа или списка получателей, списка, словаря, множества

Сноски

[7] Оператор «<code> % </code>» ещё используется для форматирования текста, но приоритетность при этом у него такая же.

[8] Оператор степени «<code> ** </code>» имеет меньший приоритет, чем арифметические или побитовые однооперандные операторы непосредственно справа от него, так, например, «<code>2**-1</code>» даёт 0,5 .

Внимание! Этот перевод, возможно, ещё не готов.
Его статус: идёт перевод

Переведено на Нотабеноиде
http://notabenoid.org/book/5672/17131

Переводчики: Hittih

Настройки

Готово:

100.00% КП = 1.0