Готовый перевод 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 "<stdin>", 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 ( "<<" | ">>" ) 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>&</code>» производит побитовую операцию «И» («AND») над целочисленными аргументами.
Оператор «<code>^</code>» производит побитовую операцию «исключающее ИЛИ» («XOR») над целочисленными аргументами.
Оператор «<code>|</code>» производит побитовую операцию «ИЛИ» («OR») над целочисленными аргументами.
5.9. Сравнения
В отличие от «C» – все операции сравнения в Питоне имеют одинаковый приоритет, который ниже, чем у любых арифметических, сдвиговых или побитовых операций. Также, в отличие от «C» , выражения типа «<code>a < b < c</code>» интерпретируются, как это принято в математике.
<code>comparison ::= or_expr ( comp_operator or_expr )*
comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="
| "is" ["not"] | ["not"] "in"</code>
Сравнения дают в результате булевы значения : «<code>True</code>» или «<code>False</code>» .
Сравнения могут соединяться в произвольные цепочки, например : «<code>x < y <= z</code>» эквивалентно «<code>x < y and y <= z</code>» , за исключением того, что «<code>y</code>» вычисляется только один раз (но в обоих вариантах «<code>z</code>» вообще не вычисляется, если «<code>x < 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 < y > z</code>» абсолютно приемлемо (хотя и не очень красиво) .
Операторы «<code><</code>» , «<code>></code>» , «<code>==</code>» , «<code>>=</code>» , «<code><=</code>» и «<code>!=</code>» сравнивают значения двух объектов. Эти объекты не обязаны иметь одинаковый тип. Если оба являются числами, то они преобразуются к общему типу. Если не числа, то операторы «<code>==</code>» и «<code>!=</code>» всегда считают объекты отличающихся типов неравными, а операторы «<code><</code>» , «<code>></code>» , «<code>>=</code>» и «<code><=</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 < float('NaN')</code>» и «<code>float('NaN') < 3</code>» вернут «<code>False</code>» .
“Байты” сравниваются поэлементно до первого несовпадения (лексикографически) , с использованием числовых значений их элементов.
“Строки” сравниваются посимвольно до первого несовпадения (лексикографически) , с использованием числовых эквивалентов (возвращаемых встроенной функцией «<code>ord()</code>» ) их элементов-симвлов.
Кортежи и списки сравниваются поэлементно до первого несовпадения (лексикографически) . Это подразумевает, что для равенства – все соответствующие элементы должны быть равны и сами последовательности должны быть одинакового типа и одинаковой длины.
Если последовательности не равны, то они упорядочиваются по первым несовпадающим элементам. Например, «<code>[1,2,x] <= [1,2,y]</code>» имеет тот же результат, что и «<code>x <= y</code>» . Если соответствующий элемент отсутствует, то более короткая последовательность меньше (идёт раньше) , например : «<code>[1,2]</code>» < «<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 <lambda>(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, <, <=, >, >=, !=, == сравнения, проверки на идентичность или вхождение
| побитовое ИЛИ
^ побитовое исключающее ИЛИ (XOR)
& побитовое И
<<, >> сдвиги
+, - сложение и вычитание
*, /, //, % умножение, деление, остаток [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
Настройки
Готово:
