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

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

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

Определения синтаксиса для ссылки на атрибут, индексирование и нарезки см. в разделе Праймериз.

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

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

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

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

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

  • Если целью является идентификатор (имя) :

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

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

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

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

    class Cls:
        x = 3             # переменная класса
    inst = Cls()
    inst.x = inst.x + 1   # записывает inst.x как 4, оставляя Cls.x как 3
    

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

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

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

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

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

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

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

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

x = [0, 1]
i = 0
i, x[i] = 1, 2         # i, затем обновляется x[i]
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].

За исключением присваивания кортежам и нескольким целям в одном операторе, присваивание, выполняемое операторами расширенного присваивания, обрабатывается так же, как и обычные присваивания. Точно так же, за исключением возможного поведения на месте, двоичная операция, выполняемая с помощью расширенного присваивания, такая же, как и обычные двоичные операции.

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

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 выражения эквивалентна:

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    # функция, которая (пока) ничего не делает

class C: pass       # класс (пока) без методов

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.

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__ (который доступен для записи). Если возникшее исключение не обработано, будут напечатаны оба исключения:

>>> try:
...     print(1 / 0)
... except Exception as exc:
...     raise RuntimeError("Случилось что-то плохое") 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: Случилось что-то плохое

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

>>> try:
...     print(1 / 0)
... except:
...     raise RuntimeError("Случилось что-то плохое")
...
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: Случилось что-то плохое

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

>>> try:
...     print(1 / 0)
... except:
...     raise RuntimeError("Случилось что-то плохое") from None
...
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: Случилось что-то плохое

Дополнительную информацию об исключениях можно найти в разделе Исключения, а информацию об обработке исключений — в разделе Оператор 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" 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 импортирован и привязан локально
import foo.bar.baz         # foo.bar.baz импортирован, foo привязан локально
import foo.bar.baz as fbb  # foo.bar.baz импортирован и привязан как fbb
from foo.bar import baz    # foo.bar.baz импортирован и привязан как baz
from foo import attr       # foo импортирован, а foo.attr привязан как 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, в которой функция станет стандартной.

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

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

Единственные строки, которые могут появиться перед оператором future:

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

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

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

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

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

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

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

Обратите внимание, что в этом утверждении нет ничего особенного:

import __future__ [as name]

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

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

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

См.также

PEP 236 - назад в __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.