Простые операторы
Простой оператор занимает одну логическую строку. Несколько простых операторов могут находиться в одной строке, разделенные точкой с запятой. Синтаксис простых операторов:
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].
За исключением присваивания кортежам и множественным целям в одном операторе, присваивание, выполняемое операторами расширенного присваивания, обрабатывается так же, как и обычные присваивания. Аналогично, за исключением возможного *помещенного на месте* поведения, бинарная операция, выполняемая оператором расширенного присваивания, такая же, как обычные бинарные операции.
Для целей, являющихся ссылками на атрибуты, тот же примечание об атрибутах класса и экземпляра применим, как и для обычных присваиваний.
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
Аналогичный механизм работает неявно, если исключение возбуждается внутри обработчика исключений или в блоке finally: предыдущее исключение затем прикрепляется в качестве атрибута __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
Дополнительную информацию об исключениях можно найти в разделе Исключения, а информацию об обработке исключений — в разделе Оператор 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 фрагмента) выполняется в два этапа:
- нахождение модуля, его загрузка и инициализация, если необходимо
- определение имени или имён в локальном пространстве имен для области видимости, где находится оператор
import.
Если оператор содержит несколько фрагментов (разделенных запятыми), то два этапа выполняются отдельно для каждого фрагмента, так как будто фрагменты были разделены в отдельные операторы импорта.
Подробное описание первого этапа, поиска и загрузки модулей, приведено в разделе о системе импорта, где также описаны различные типы пакетов и модулей, которые могут быть импортированы, а также все возможные способы настройки системы импорта. Обратите внимание, что ошибки на этом этапе могут указывать на то, что модуль не был найден или произошла ошибка во время его инициализации, включая выполнение кода модуля.
Если запрашиваемый модуль успешно получен, он станет доступным в локальном пространстве имен одним из трех способов:
- Если имя модуля следует за
as, то имя, следущее заas, непосредственно связывается с импортированным модулем. - Если другое имя не указано, а импортируемый модуль является модулем верхнего уровня, имя модуля связывается в локальном пространстве имен как ссылка на импортированный модуль.
- Если импортируемый модуль не является модулем верхнего уровня, то имя верхнего уровня пакета, содержащего модуль, связывается в локальном пространстве имен как ссылка на пакет верхнего уровня. Импортируемый модуль должен быть доступен по его полному квалифицированному имени, а не напрямую.
Форма from использует немного более сложный процесс:
- найти модуль, указанный в
fromфрагменте, загрузить и инициализировать его, если необходимо; -
для каждого из идентификаторов, указанных в
importфрагментах:- проверить, есть ли у импортированного модуля атрибут с таким именем
- если нет, попытаться импортировать подмодуль с этим именем, а затем снова проверить импортированный модуль на наличие этого атрибута
- если атрибут не найден, генерируется исключение
ImportError. - в противном случае ссылка на это значение сохраняется в локальном пространстве имен, используя имя из
asфрагмента, если оно присутствует, в противном случае используется имя атрибута
Примеры:
import foo # foo imported and bound locally import foo.bar.baz # foo.bar.baz imported, foo bound locally import foo.bar.baz as fbb # foo.bar.baz imported and bound as fbb from foo.bar import baz # foo.bar.baz imported and 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 - Назад к __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, не должны конфликтовать с предварительно существующими привязками в локальной области видимости.
© 2001–2022 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.8/reference/simple_stmts.html