Spec-Zone.ru › Python 3.9

Простые операторы

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

simple_stmt ::=  expression_stmt
                 | assert_stmt
                 | assignment_stmt
                 | augmented_assignment_stmt
                 | annotated_assignment_stmt
                 | pass_stmt
                 | del_stmt
                 | return_stmt
                 | yield_stmt
                 | raise_stmt
                 | break_stmt
                 | continue_stmt
                 | import_stmt
                 | future_stmt
                 | global_stmt
                 | nonlocal_stmt

7.1. Операторы выражений

Операторы выражений используются (в основном интерактивно) для вычисления и записи значения или (обычно) для вызова процедуры (функции, которая не возвращает значимого результата; в Python процедуры возвращают значение None). Другие использования операторов выражений разрешены и иногда полезны. Синтаксис оператора выражения:

expression_stmt ::=  starred_expression

Оператор выражения вычисляет список выражений (который может быть единственным выражением).

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

7.2. Операторы присваивания

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

assignment_stmt ::=  (target_list "=")+ (starred_expression | yield_expression)
target_list     ::=  target ("," target)* [","]
target          ::=  identifier
                     | "(" [target_list] ")"
                     | "[" [target_list] "]"
                     | attributeref
                     | subscription
                     | slicing
                     | "*" target

(См. раздел Основные выражения для определений синтаксиса attributeref, subscription и slicing).

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

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

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

  • Если список целей состоит из одного целевого объекта без заключительной запятой, необязательно в скобках, объект присваивается этому целевому объекту.
  • В противном случае:

    • Если список целей содержит один целевой объект, помеченный звёздочкой, называемый «звездочным» целевым объектом: объект должен быть итерируемым с не менее чем столько же элементами, сколько целевых объектов в списке целей минус один. Первые элементы итерируемого объекта присваиваются целевым объектам перед звездочным целевым объектом слева направо. Последние элементы итерируемого объекта присваиваются целевым объектам после звездочного целевого объекта. Список оставшихся элементов в итерируемом объекте затем присваивается звездочному целевому объекту (список может быть пустым).
    • В противном случае объект должен быть итерируемым с таким же количеством элементов, как целевых объектов в списке целей, и элементы присваиваются соответствующим целевым объектам слева направо.

Присваивание объекта одному целевому объекту определяется рекурсивно следующим образом.

  • Если целевой объект — идентификатор (имя):

    • Если имя не встречается в операторе global или nonlocal в текущем блоке кода: имя связывается с объектом в текущем локальном пространстве имён.
    • В противном случае: имя связывается с объектом в глобальном пространстве имён или внешнем пространстве имён, определяемом nonlocal, соответственно.

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

  • Если целевой объект — ссылка на атрибут: выражение основного объекта в ссылке вычисляется. Оно должно возвращать объект с присваиваемыми атрибутами; если это не так, вызывается TypeError. Затем этот объект запрашивается для присваивания объекта присваиваемого значения заданному атрибуту; если он не может выполнить присваивание, он вызывает исключение (обычно, но не обязательно, AttributeError).

    Примечание: Если объект является экземпляром класса, а ссылка на атрибут встречается по обе стороны от оператора присваивания, выражение правой части, a.x может получить доступ к атрибуту экземпляра или (если атрибут экземпляра не существует) к атрибуту класса. Целевое значение левой части a.x всегда устанавливается как атрибут экземпляра, создавая его при необходимости. Таким образом, два появления a.x не обязательно ссылаются на один и тот же атрибут: если выражение правой части ссылается на атрибут класса, левая часть создаёт новый атрибут экземпляра в качестве целевого значения присваивания:

    class Cls:
        x = 3             # class variable
    inst = Cls()
    inst.x = inst.x + 1   # writes inst.x as 4 leaving Cls.x as 3
    

    Это описание не обязательно относится к атрибутам-дескрипторам, таким как свойства, созданные с помощью property().

  • Если целевой объект — подстановка: выражение основного объекта в ссылке вычисляется. Оно должно возвращать либо изменяемый последовательный объект (такой как список), либо объект отображения (такой как словарь). Далее вычисляется выражение индекса.

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

    Если основной объект является объектом отображения (таким как словарь), индекс должен иметь тип, совместимый с типом ключа отображения, и объект отображения затем запрашивается для создания пары ключ/значение, которая сопоставляет индекс присвоенному объекту. Это может либо заменить существующую пару ключ/значение тем же значением ключа, либо вставить новую пару ключ/значение (если ключ с тем же значением не существовал).

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

  • Если целевой объект — срезание: выражение основного объекта в ссылке вычисляется. Оно должно возвращать изменяемый последовательный объект (например, список). Присваиваемый объект должен быть последовательным объектом того же типа. Далее вычисляются выражения нижней и верхней границ, если они присутствуют; значения по умолчанию — ноль и длина последовательности. Границы должны вычисляться до целых чисел. Если какая-либо граница отрицательная, к ней добавляется длина последовательности. Полученные границы усекаются до значений между нулём и длиной последовательности включительно. Наконец, объект последовательности запрашивается для замены среза элементами присваиваемой последовательности. Длина среза может отличаться от длины присваиваемой последовательности, тем самым изменяя длину целевой последовательности, если целевая последовательность это позволяет.

Подробность реализации CPython: В текущей реализации синтаксис целевых объектов принимается таким же, как и для выражений, а некорректный синтаксис отклоняется на стадии генерации кода, что приводит к менее подробным сообщениям об ошибках.

Хотя определение присваивания подразумевает, что пересечения между левой и правой частями являются «одновременными» (например, a, b = b, a меняет два переменных), пересечения *внутри* набора присваиваемых переменных происходят слева направо, что иногда приводит к путанице. Например, следующая программа выводит [0, 2]:

x = [0, 1]
i = 0
i, x[i] = 1, 2         # i is updated, then x[i] is updated
print(x)

См. также

PEP 3132 - Расширенное распаковывание итерируемых объектов

Спецификация для *target функции.

7.2.1. Операторы расширенного присваивания

Расширенное присваивание — это комбинация бинарной операции и оператора присваивания в одном операторе:

augmented_assignment_stmt ::=  augtarget augop (expression_list | yield_expression)
augtarget                 ::=  identifier | attributeref | subscription | slicing
augop                     ::=  "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**="
                               | ">>=" | "<<=" | "&=" | "^=" | "|="

(См. раздел Основные выражения для определений синтаксиса последних трёх символов.)

Расширенное присваивание вычисляет целевой объект (который, в отличие от обычных операторов присваивания, не может быть распаковкой) и список выражений, выполняет бинарную операцию, специфичную для типа присваивания, над двумя операндами и присваивает результат исходному целевому объекту. Целевой объект вычисляется только один раз.

Выражение расширенного присваивания, например x += 1 можно переписать как x = x + 1 для достижения похожего, но не совсем одинакового эффекта. В расширенной версии x вычисляется только один раз. Кроме того, когда это возможно, фактическая операция выполняется *на месте*, что означает, что вместо создания нового объекта и присваивания его целевому объекту, старый объект изменяется вместо этого.

В отличие от обычных присваиваний, при расширенном присваивании левая часть вычисляется *до* вычисления правой части. Например, a[i] += f(x) сначала ищет a[i], затем вычисляет f(x) и выполняет сложение, а затем записывает результат обратно в a[i].

За исключением присваивания кортежам и множественным целевым объектам в одном операторе, присваивание, выполняемое операторами расширенного присваивания, обрабатывается так же, как и обычные операторы присваивания. Аналогично, за исключением возможного *in-place* поведения, бинарная операция, выполняемая расширенным присваиванием, такая же, как и обычные бинарные операции.

Для целевых объектов, которые являются ссылками на атрибуты, применяется то же *замечание относительно атрибутов класса и экземпляров*, что и для обычных присваиваний.

7.2.2. Аннотированные операторы присваивания

Аннотация присваивания — это комбинация аннотации переменной или атрибута и необязательного оператора присваивания в одном операторе:

annotated_assignment_stmt ::=  augtarget ":" expression
                               ["=" (starred_expression | yield_expression)]

Разница с обычными операторами присваивания заключается в том, что разрешен только один целевой объект.

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

Для выражений в качестве целевых объектов аннотации вычисляются, если они находятся в области класса или модуля, но не сохраняются.

Если имя аннотировано в области функции, то это имя является локальным для этой области. Аннотации никогда не вычисляются и не сохраняются в областях функций.

Если присутствует правая часть, аннотированный оператор присваивания выполняет фактическое присваивание перед вычислением аннотаций (если применимо). Если правой части нет для выражения-целевого объекта, то интерпретатор вычисляет целевой объект, за исключением последнего вызова __setitem__() или __setattr__().

См. также

PEP 526 — Синтаксис аннотаций переменных

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

PEP 484 — Указатели типов

Предложение, которое добавило модуль typing для предоставления стандартного синтаксиса аннотаций типов, который может использоваться в инструментах статического анализа и IDE.

Изменено в версии 3.8: Теперь аннотированные операторы присваивания допускают те же выражения в правой части, что и обычные операторы присваивания. Раньше некоторые выражения (например, не-скобочные кортежи) вызывали ошибку синтаксиса.

7.3. Оператор assert

Операторы assert — удобный способ вставки отладочных утверждений в программу:

assert_stmt ::=  "assert" expression ["," expression]

Простая форма, assert expression, эквивалентна

if __debug__:
    if not expression: raise AssertionError

Расширенная форма, assert expression1, expression2, эквивалентна

if __debug__:
    if not expression1: raise AssertionError(expression2)

Эти эквивалентности предполагают, что __debug__ и AssertionError ссылаются на встроенные переменные с такими именами. В текущей реализации встроенная переменная __debug__ имеет значение True в обычных условиях, False при запросе оптимизации (опция командной строки -O). Текущий генератор кода не генерирует код для оператора assert, когда оптимизация запрошена во время компиляции. Обратите внимание, что не нужно включать в сообщение об ошибке исходный код выражения, которое потерпело неудачу; оно будет отображено как часть трассировки стека.

Присваивания переменной __debug__ запрещены. Значение встроенной переменной определяется при запуске интерпретатора.

7.4. Оператор pass

pass_stmt ::=  "pass"

pass — оператор без действия — при его выполнении ничего не происходит. Он полезен в качестве заполнителя, когда синтаксически требуется оператор, но не нужно выполнять код, например:

def f(arg): pass    # a function that does nothing (yet)

class C: pass       # a class with no methods (yet)

7.5. Оператор del

del_stmt ::=  "del" target_list

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

Удаление списка целевых объектов рекурсивно удаляет каждый целевой объект слева направо.

Удаление имени удаляет привязку этого имени из локального или глобального пространства имён в зависимости от того, встречается ли имя в операторе global в том же блоке кода. Если имя не привязано, будет поднято исключение NameError.

Удаление ссылок на атрибуты, индексов и срезов передаётся основному объекту; удаление среза в общем случае эквивалентно присваиванию пустого среза соответствующего типа (но даже это определяется срезуемым объектом).

Изменено в версии 3.2: Раньше удаление имени из локального пространства имён было недопустимо, если оно встречалось как свободная переменная во вложенном блоке.

7.6. Оператор return

return_stmt ::=  "return" [expression_list]

return может встречаться только синтаксически внутри определения функции, а не внутри вложенного определения класса.

Если присутствует список выражений, он вычисляется; в противном случае подставляется None.

return завершает текущий вызов функции со значением возврата, заданным списком выражений (или None).

Когда return передаёт управление за пределы оператора try с клаузой finally, эта finally клауза выполняется перед фактическим выходом из функции.

В функции-генераторе оператор return указывает, что генератор закончен, и вызовет повышение StopIteration. Возвращаемое значение (если таковое есть) используется в качестве аргумента для создания StopIteration и становится атрибутом StopIteration.value.

В асинхронной функции-генераторе пустой оператор return указывает, что асинхронный генератор закончен, и вызовет повышение StopAsyncIteration. Непустой оператор return является синтаксической ошибкой в асинхронной функции-генераторе.

7.7. Оператор yield

yield_stmt ::=  yield_expression

Оператор yield семантически эквивалентен выражению yield-выражение. Оператор yield может использоваться для пропуска скобок, которые в противном случае были бы необходимы в эквивалентном операторе yield-выражения. Например, операторы yield

yield <expr>
yield from <expr>

эквивалентны операторам yield-выражений

(yield <expr>)
(yield from <expr>)

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

Для получения полной информации о семантике yield см. раздел yield-выражения.

7.8. Оператор raise

raise_stmt ::=  "raise" [expression ["from" expression]]

Если выражения отсутствуют, оператор raise повторно поднимает исключение, которое в данный момент обрабатывается, что также известно как активное исключение. Если в данный момент активного исключения нет, поднимается исключение RuntimeError со сообщением об ошибке.

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

Тип исключения — это класс экземпляра исключения, а значение — сам экземпляр.

Объект отслеживания стека обычно создаётся автоматически при возникновении исключения и прикрепляется к нему как атрибут __traceback__, который можно перезаписать. Вы можете создать исключение и установить собственный отслеживатель стека в один шаг, используя метод исключения with_traceback() (который возвращает тот же экземпляр исключения, но с установленным в качестве аргумента отслеживателем стека), например:

raise Exception("foo occurred").with_traceback(tracebackobj)

Оператор from используется для цепочек исключений: если задано, второе выражение должно быть другим классом исключения или экземпляром. Если второе выражение — экземпляр исключения, он будет прикреплен к поднятому исключению как атрибут __cause__ (который можно перезаписать). Если выражение — класс исключения, класс будет создан, а полученный экземпляр исключения будет прикреплен к поднятому исключению как атрибут __cause__. Если поднятое исключение не обрабатывается, оба исключения будут напечатаны:

>>> try:
...     print(1 / 0)
... except Exception as exc:
...     raise RuntimeError("Something bad happened") from exc
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: division by zero

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: Something bad happened

Аналогичный механизм работает неявно, если новое исключение поднимается, когда исключение уже обрабатывается. Исключение может быть обработано, когда используется блок except или finally, или оператор with. Предыдущее исключение затем прикрепляется как атрибут __context__ нового исключения:

>>> try:
...     print(1 / 0)
... except:
...     raise RuntimeError("Something bad happened")
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: Something bad happened

Цепочки исключений можно явно подавить, указав None в блоке from:

>>> try:
...     print(1 / 0)
... except:
...     raise RuntimeError("Something bad happened") from None
...
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: Something bad happened

Дополнительную информацию об исключениях можно найти в разделе Исключения, а информацию об обработке исключений — в разделе Оператор try.

Изменено в версии 3.3: None теперь разрешено в качестве Y в raise X from Y.

Добавлен в версии 3.3: Атрибут __suppress_context__ для подавления автоматического отображения контекста исключения.

7.9. Оператор break

break_stmt ::=  "break"

Оператор break может быть использован только в структуре цикла for или while, но не внутри определения функции или класса в пределах этого цикла.

Он завершает ближайший внешний цикл, пропуская необязательный блок else , если таковой имеется.

Если цикл for завершается с помощью break, целевой объект цикла сохраняет своё текущее значение.

Когда break передаёт управление за пределы оператора try с блоком finally, этот блок finally выполняется перед фактическим выходом из цикла.

7.10. Оператор continue

continue_stmt ::=  "continue"

Оператор continue может быть использован только в структуре цикла for или while, но не внутри определения функции или класса в пределах этого цикла. Он продолжает выполнение с следующей итерацией ближайшего внешнего цикла.

Когда continue передаёт управление за пределы оператора try с блоком finally, этот блок finally выполняется перед фактическим началом следующей итерации цикла.

7.11. Оператор import

import_stmt     ::=  "import" module ["as" identifier] ("," module ["as" identifier])*
                     | "from" relative_module "import" identifier ["as" identifier]
                     ("," identifier ["as" identifier])*
                     | "from" relative_module "import" "(" identifier ["as" identifier]
                     ("," identifier ["as" identifier])* [","] ")"
                     | "from" relative_module "import" "*"
module          ::=  (identifier ".")* identifier
relative_module ::=  "."* module | "."+

Основной оператор импорта (без from фрагмента) выполняется в два этапа:

  1. найти модуль, загрузить и инициализировать его при необходимости
  2. определить имя или имена в локальном пространстве имён для области, где находится оператор import.

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

Подробное описание первого этапа, поиска и загрузки модулей, приведено в разделе о системе импорта, в котором также описываются различные типы пакетов и модулей, которые могут быть импортированы, а также все возможности для настройки системы импорта. Обратите внимание, что ошибки на этом этапе могут указывать либо на то, что модуль не был найден, либо на то, что произошла ошибка при инициализации модуля, включая выполнение кода модуля.

Если запрашиваемый модуль успешно получен, он будет доступен в локальном пространстве имён одним из трёх способов:

  • Если имя модуля следует за as, тогда имя, следующее за as, напрямую связывается с импортированным модулем.
  • Если не указано другое имя, и импортируемый модуль является модулем верхнего уровня, имя модуля связывается в локальном пространстве имён как ссылка на импортированный модуль.
  • Если импортируемый модуль не является модулем верхнего уровня, тогда имя верхнего уровня пакета, содержащего модуль, связывается в локальном пространстве имён как ссылка на пакет верхнего уровня. К импортированному модулю необходимо обращаться с использованием его полного квалифицированного имени, а не напрямую.

Форма from использует несколько более сложный процесс:

  1. найти модуль, указанный в from фрагменте, загрузить и инициализировать его при необходимости;
  2. для каждого идентификатора, указанного в import фрагментах:

    1. проверить, есть ли у импортированного модуля атрибут с таким именем
    2. если нет, попытаться импортировать подмодуль с таким именем, а затем снова проверить импортированный модуль на наличие этого атрибута
    3. если атрибут не найден, генерируется исключение ImportError.
    4. в противном случае ссылка на это значение сохраняется в локальном пространстве имён, используя имя в as фрагменте, если оно присутствует, в противном случае используется имя атрибута

Примеры:

import foo                 # foo imported and bound locally
import foo.bar.baz         # foo, foo.bar, and foo.bar.baz imported, foo bound locally
import foo.bar.baz as fbb  # foo, foo.bar, and foo.bar.baz imported, foo.bar.baz bound as fbb
from foo.bar import baz    # foo, foo.bar, and foo.bar.baz imported, foo.bar.baz bound as baz
from foo import attr       # foo imported and foo.attr bound as attr

Если список идентификаторов заменён звёздочкой ('*'), все публичные имена, определённые в модуле, связываются в локальном пространстве имён для области, где находится оператор import.

Публичные имена, определённые модулем, определяются путём проверки пространства имён модуля на наличие переменной с именем __all__; если она определена, она должна быть последовательностью строк, которые являются именами, определёнными или импортированными этим модулем. Имена, указанные в __all__, считаются публичными и должны существовать. Если __all__ не определена, набор публичных имён включает все имена, найденные в пространстве имён модуля, которые не начинаются с символа подчёркивания ('_'). __all__ должен содержать весь публичный API. Он предназначен для того, чтобы случайно не экспортировать элементы, которые не являются частью API (например, модули библиотек, которые были импортированы и использовались внутри модуля).

Форма импорта с подстановкой звёздочки — from module import * — разрешена только на уровне модуля. Попытка использовать её в определениях классов или функций вызовет исключение SyntaxError.

При указании импортируемого модуля не нужно указывать его полное имя. Если модуль или пакет находится внутри другого пакета, возможно выполнить относительный импорт в пределах того же верхнего пакета, без необходимости упоминания имени пакета. Используя ведущие точки в указанном модуле или пакете после from, можно указать, на сколько уровней вверх следует перемещаться по иерархии текущего пакета, не указывая точных имён. Одна ведущая точка означает текущий пакет, в котором находится импортирующий модуль. Две точки означают переход на один уровень вверх по пакетам. Три точки — на два уровня вверх и т. д. Поэтому если выполнить from . import mod из модуля в пакете pkg, то вы импортируете pkg.mod. Если выполнить from ..subpkg2 import mod изнутри pkg.subpkg1, вы импортируете pkg.subpkg2.mod. Спецификация относительных импортов содержится в разделе Относительные импорты пакетов.

importlib.import_module() предназначен для поддержки приложений, которые динамически определяют модули для загрузки.

Вызывает событие аудита аудита import с аргументами module, filename, sys.path, sys.meta_path, sys.path_hooks.

7.11.1. Операторы будущего

Оператор будущего — это директива компилятору о том, что данный модуль должен быть скомпилирован с использованием синтаксиса или семантики, которые будут доступны в указанной будущей версии Python, где функция станет стандартной.

Оператор будущего предназначен для облегчения миграции к будущим версиям Python, которые вводят несовместимые изменения в язык. Он позволяет использовать новые функции на уровне отдельных модулей до выпуска, в котором функция становится стандартной.

future_stmt ::=  "from" "__future__" "import" feature ["as" identifier]
                 ("," feature ["as" identifier])*
                 | "from" "__future__" "import" "(" feature ["as" identifier]
                 ("," feature ["as" identifier])* [","] ")"
feature     ::=  identifier

Оператор будущего должен располагаться в начале модуля. Единственные строки, которые могут находиться перед оператором будущего, — это:

  • строка документации модуля (если есть),
  • комментарии,
  • пустые строки и
  • другие операторы будущего.

Единственная функция, для которой требуется использование оператора будущего, — это annotations (см. PEP 563).

Все исторические функции, включённые оператором будущего, по-прежнему распознаются Python 3. Список включает absolute_import, division, generators, generator_stop, unicode_literals, print_function, nested_scopes и with_statement. Все они избыточны, потому что всегда включены и сохранены только для обратной совместимости.

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

Для любой конкретной версии компилятор знает, какие имена функций определены, и генерирует ошибку компиляции, если оператор будущего содержит не известную ему функцию.

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

Интересная семантика времени выполнения зависит от конкретной функции, включённой оператором будущего.

Обратите внимание, что в операторе:

import __future__ [as name]

нет ничего особенного; это обычный оператор импорта без специальной семантики или ограничений синтаксиса.

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

Оператор будущего, введённый в интерактивном интерпретаторе, будет действовать на протяжении всей сессии интерпретатора. Если интерпретатор запускается с опцией -i, получает имя скрипта для выполнения и скрипт содержит оператор будущего, он будет действовать в интерактивной сессии, начатой после выполнения скрипта.

См. также

PEP 236 - Back to the __future__

Исходное предложение для механизма __future__.

7.12. Оператор global

global_stmt ::=  "global" identifier ("," identifier)*

Оператор global представляет собой объявление, которое действует для всего текущего блока кода. Это означает, что перечисленные идентификаторы должны интерпретироваться как глобальные. Было бы невозможно присвоить значение глобальной переменной без global, хотя свободные переменные могут ссылаться на глобальные переменные без объявления их глобальными.

Имена, перечисленные в операторе global, не должны использоваться в том же блоке кода до этого оператора global.

Имена, перечисленные в операторе global, не должны быть определены в качестве формальных параметров или в качестве целевого объекта цикла for, определения класса class, определения функции, оператора import или аннотации переменной.

Деталь реализации CPython: Текущая реализация не выполняет некоторые из этих ограничений, но программы не должны злоупотреблять этой свободой, поскольку будущие реализации могут их применить или безмолвно изменить значение программы.

Примечание программисту: global — это директива для парсера. Она применяется только к коду, разобранному одновременно с оператором global. В частности, оператор global , содержащийся в строке или объекте кода, переданном встроенной функции exec(), не влияет на блок кода, содержащий вызов функции, и код, содержащийся в такой строке, не затрагивается операторами global в коде, содержащем вызов функции. То же самое относится к функциям eval() и compile().

7.13. Оператор nonlocal

nonlocal_stmt ::=  "nonlocal" identifier ("," identifier)*

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

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

Имена, перечисленные в операторе nonlocal, не должны конфликтовать с существующими привязками в локальном пространстве имён.

См. также

PEP 3104 - Доступ к именам в внешних пространствах имён

Спецификация оператора nonlocal.

© 2001–2022 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.9/reference/simple_stmts.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API