Простые операторы
Простой оператор состоит из одной логической строки. Несколько простых операторов могут находиться в одной строке, разделённые точкой с запятой. Синтаксис простых операторов:
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 # 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>
print(1 / 0)
~~^~~
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>
raise RuntimeError("Something bad happened") from exc
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>
print(1 / 0)
~~^~~
ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
raise RuntimeError("Something bad happened")
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__ для подавления автоматического отображения контекста исключения.
Изменено в версии 3.11: Если трассировка активного исключения изменяется в блоке except, последующий оператор raise повторно поднимает исключение с изменённой трассировкой. Раньше исключение поднималось повторно с трассировкой, которая была у него во время захвата.
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 части) выполняется в два этапа:
- найти модуль, загрузить и инициализировать его при необходимости
- определить имя или имена в локальном пространстве имен для области, где находится оператор
import.
Когда оператор содержит несколько частей (разделенных запятыми), эти два шага выполняются по отдельности для каждой части, как будто части были разделены в отдельные операторы импорта.
Подробности первого шага, поиска и загрузки модулей, описаны подробнее в разделе по системе импорта, где также описаны различные типы пакетов и модулей, которые можно импортировать, а также все хуки, которые могут быть использованы для настройки системы импорта. Обратите внимание, что ошибки на этом этапе могут указывать либо на то, что модуль не был найден, или на то, что произошла ошибка при инициализации модуля, включая выполнение кода модуля.
Если запрашиваемый модуль успешно получен, он будет доступен в локальном пространстве имен одним из трех способов:
- Если имя модуля следует за
as, то имя, следующее заas, связывается непосредственно с импортированным модулем. - Если другое имя не указано, а импортируемый модуль является модулем верхнего уровня, имя модуля связывается в локальном пространстве имен как ссылка на импортированный модуль
- Если импортируемый модуль не является модулем верхнего уровня, то имя верхнего уровня пакета, содержащего модуль, связывается в локальном пространстве имен как ссылка на пакет верхнего уровня. Импортированный модуль необходимо обращаться к нему используя полное полное имя, а не напрямую
Форма from использует немного более сложный процесс:
- найти модуль, указанный в
fromчасти, загрузить и инициализировать его при необходимости; -
для каждого идентификатора, указанного в
importчастях:- проверить, имеет ли импортированный модуль атрибут с таким именем
- если нет, попытаться импортировать подмодуль с таким именем и затем снова проверить импортированный модуль на наличие этого атрибута
- если атрибут не найден, возникает
ImportError. - в противном случае ссылка на это значение хранится в локальном пространстве имен, используя имя в
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. The global statement
global_stmt ::= "global" identifier ("," identifier)*
The global statement is a declaration that applies to the entire current code block. It indicates that the listed identifiers are to be interpreted as global variables. It would be impossible to assign to a global variable without global, although free variables may refer to global variables without being declared global.
Names listed in a global statement must not be used in the same code block textually before that global statement.
Names listed in a global statement must not be defined as formal parameters, or as targets in with statements or except clauses, or in a for target list, class definition, function definition, import statement, or variable annotation.
CPython implementation detail: The current implementation does not enforce some of these restrictions, but programs should not abuse this freedom, as future implementations may enforce them or silently change the meaning of the program.
Programmer’s note: global is a directive to the parser. It applies only to code parsed at the same time as the global statement. In particular, a global statement contained in a string or code object supplied to the built-in exec() function does not affect the code block containing the function call, and code contained in such a string is unaffected by global statements in the code containing the function call. The same applies to the eval() and compile() functions.
7.13. The nonlocal statement
nonlocal_stmt ::= "nonlocal" identifier ("," identifier)*
The nonlocal statement causes the listed identifiers to refer to previously bound variables in the nearest enclosing scope, excluding globals. This is important because the default behavior for binding is to search the local namespace first. The statement allows encapsulated code to rebind variables outside of the local scope, besides the global (module) scope.
Names listed in a nonlocal statement, unlike those listed in a global statement, must refer to pre-existing bindings in an enclosing scope (the scope in which a new binding should be created cannot be determined unambiguously).
Names listed in a nonlocal statement must not collide with pre-existing bindings in the local scope.
© 2001–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.11/reference/simple_stmts.html